/** * Generate a filename for a library file. * @param $type int LIBRARY_FILE_TYPE_... * @param $originalFileName string * @return string */ function generateFileName($type, $originalFileName) { $libraryFileDao = DAORegistry::getDAO('LibraryFileDAO'); $suffix = $this->getFileSuffixFromType($type); $ext = $this->getExtension($originalFileName); $truncated = $this->truncateFileName($originalFileName, 127 - PKPString::strlen($suffix) - 1); $baseName = PKPString::substr($truncated, 0, PKPString::strpos($originalFileName, $ext) - 1); // Try a simple syntax first $fileName = $baseName . '-' . $suffix . '.' . $ext; if (!$libraryFileDao->filenameExists($this->contextId, $fileName)) { return $fileName; } for ($i = 1;; $i++) { $fullSuffix = $suffix . '-' . $i; //truncate more if necessary $truncated = $this->truncateFileName($originalFileName, 127 - PKPString::strlen($fullSuffix) - 1); // get the base name and append the suffix $baseName = PKPString::substr($truncated, 0, PKPString::strpos($originalFileName, $ext) - 1); //try the following $fileName = $baseName . '-' . $fullSuffix . '.' . $ext; if (!$libraryFileDao->filenameExists($this->contextId, $fileName)) { return $fileName; } } }
/** * Split a string into a clean array of keywords * @param $text string * @param $allowWildcards boolean * @return array of keywords */ static function filterKeywords($text, $allowWildcards = false) { $minLength = Config::getVar('search', 'min_word_length'); $stopwords = self::_loadStopwords(); // Join multiple lines into a single string if (is_array($text)) { $text = join("\n", $text); } $cleanText = Core::cleanVar($text); // Remove punctuation $cleanText = PKPString::regexp_replace('/[!"\\#\\$%\'\\(\\)\\.\\?@\\[\\]\\^`\\{\\}~]/', '', $cleanText); $cleanText = PKPString::regexp_replace('/[\\+,:;&\\/<=>\\|\\\\]/', ' ', $cleanText); $cleanText = PKPString::regexp_replace('/[\\*]/', $allowWildcards ? '%' : ' ', $cleanText); $cleanText = PKPString::strtolower($cleanText); // Split into words $words = PKPString::regexp_split('/\\s+/', $cleanText); // FIXME Do not perform further filtering for some fields, e.g., author names? // Remove stopwords $keywords = array(); foreach ($words as $k) { if (!isset($stopwords[$k]) && PKPString::strlen($k) >= $minLength && !is_numeric($k)) { $keywords[] = PKPString::substr($k, 0, SEARCH_KEYWORD_MAX_LENGTH); } } return $keywords; }
/** * Display the payment form * @param $queuedPaymentId int * @param $queuedPayment QueuedPayment * @param $request PKPRequest */ function displayPaymentForm($queuedPaymentId, $queuedPayment, $request) { if (!$this->isConfigured()) { return false; } AppLocale::requireComponents(LOCALE_COMPONENT_APP_COMMON); $journal = $request->getJournal(); $user = $request->getUser(); $params = array('charset' => Config::getVar('i18n', 'client_charset'), 'business' => $this->getSetting($journal->getId(), 'selleraccount'), 'item_name' => $queuedPayment->getName(), 'item_description' => $queuedPayment->getDescription(), 'amount' => sprintf('%.2F', $queuedPayment->getAmount()), 'quantity' => 1, 'no_note' => 1, 'no_shipping' => 1, 'currency_code' => $queuedPayment->getCurrencyCode(), 'lc' => PKPString::substr(AppLocale::getLocale(), 3), 'custom' => $queuedPaymentId, 'notify_url' => $request->url(null, 'payment', 'plugin', array($this->getName(), 'ipn')), 'return' => $queuedPayment->getRequestUrl(), 'cancel_return' => $request->url(null, 'payment', 'plugin', array($this->getName(), 'cancel')), 'first_name' => $user ? $user->getFirstName() : '', 'last_name' => $user ? $user->getLastname() : '', 'item_number' => $queuedPayment->getAssocId(), 'cmd' => '_xclick'); AppLocale::requireComponents(LOCALE_COMPONENT_APP_COMMON); $templateMgr = TemplateManager::getManager($request); $templateMgr->assign('params', $params); $templateMgr->assign('paypalFormUrl', $this->getSetting($journal->getId(), 'paypalurl')); $templateMgr->display($this->getTemplatePath() . 'paymentForm.tpl'); return true; }
/** * Construct an array of search strings from a citation * description and an array of search templates. * The templates may contain the placeholders * %aulast%: the first author's surname * %au%: the first author full name * %title%: the article-title (if it exists), * otherwise the source * %date%: the publication year * %isbn%: ISBN * @param $searchTemplates an array of templates * @param $citationDescription MetadataDescription * @return array */ function constructSearchStrings(&$searchTemplates, &$citationDescription) { // Convert first authors' name description to a string import('lib.pkp.plugins.metadata.nlm30.filter.Nlm30NameSchemaPersonStringFilter'); $personStringFilter = new Nlm30NameSchemaPersonStringFilter(); // Retrieve the authors $firstAuthorSurname = $firstAuthor = ''; $authors = $citationDescription->getStatement('person-group[@person-group-type="author"]'); if (is_array($authors) && count($authors)) { $firstAuthorSurname = (string) $authors[0]->getStatement('surname'); $firstAuthor = $personStringFilter->execute($authors[0]); } // Retrieve the editors $firstEditorSurname = $firstEditor = ''; $editors = $citationDescription->getStatement('person-group[@person-group-type="editor"]'); if (is_array($editors) && count($editors)) { $firstEditorSurname = (string) $editors[0]->getStatement('surname'); $firstEditor = $personStringFilter->execute($editors[0]); } // Retrieve (default language) title $title = (string) ($citationDescription->hasStatement('article-title') ? $citationDescription->getStatement('article-title') : $citationDescription->getStatement('source')); // Extract the year from the publication date $year = (string) $citationDescription->getStatement('date'); $year = PKPString::strlen($year) > 4 ? PKPString::substr($year, 0, 4) : $year; // Retrieve ISBN $isbn = (string) $citationDescription->getStatement('isbn'); // Replace the placeholders in the templates $searchStrings = array(); foreach ($searchTemplates as $searchTemplate) { // Try editors and authors separately $searchStrings[] = str_replace(array('%aulast%', '%au%', '%title%', '%date%', '%isbn%'), array($firstAuthorSurname, $firstAuthor, $title, $year, $isbn), $searchTemplate); $searchStrings[] = str_replace(array('%aulast%', '%au%', '%title%', '%date%', '%isbn%'), array($firstEditorSurname, $firstEditor, $title, $year, $isbn), $searchTemplate); } // Remove empty or duplicate searches $searchStrings = array_map(array('PKPString', 'trimPunctuation'), $searchStrings); $searchStrings = array_unique($searchStrings); $searchStrings = arrayClean($searchStrings); return $searchStrings; }
/** * Transform a single NLM name description to a person string. * NB: We use the style: surname suffix, initials (first-name) prefix * which is relatively easy to parse back. * @param $personDescription MetadataDescription|'et-al' * @return string */ function _flattenPersonDescription(&$personDescription) { // Handle et-al if (is_string($personDescription) && $personDescription == PERSON_STRING_FILTER_ETAL) { return 'et al'; } $nameVars['%surname%'] = (string) $personDescription->getStatement('surname'); $givenNames = $personDescription->getStatement('given-names'); $nameVars['%firstname%'] = $nameVars['%initials%'] = ''; if (is_array($givenNames) && count($givenNames)) { if (PKPString::strlen($givenNames[0]) > 1) { $nameVars['%firstname%'] = array_shift($givenNames); } foreach ($givenNames as $givenName) { $nameVars['%initials%'] .= PKPString::substr($givenName, 0, 1) . '.'; } } if (!empty($nameVars['%initials%'])) { $nameVars['%initials%'] = ' ' . $nameVars['%initials%']; } $nameVars['%prefix%'] = (string) $personDescription->getStatement('prefix'); if (!empty($nameVars['%prefix%'])) { $nameVars['%prefix%'] = ' ' . $nameVars['%prefix%']; } $nameVars['%suffix%'] = (string) $personDescription->getStatement('suffix'); if (!empty($nameVars['%suffix%'])) { $nameVars['%suffix%'] = ' ' . $nameVars['%suffix%']; } // Fill placeholders in person template. $personString = str_replace(array_keys($nameVars), array_values($nameVars), $this->getTemplate()); // Remove empty brackets and trailing/leading whitespace $personString = trim(str_replace('()', '', $personString)); return $personString; }
/** * Fills the given citation object with * meta-data retrieved from PubMed. * @param $pmid string * @return MetadataDescription */ function &_lookup($pmid) { $nullVar = null; // Use eFetch to get XML metadata for the given PMID $lookupParams = array('db' => 'pubmed', 'mode' => 'xml', 'tool' => 'pkp-wal', 'id' => $pmid); if (!is_null($this->getEmail())) { $lookupParams['email'] = $this->getEmail(); } // Call the eFetch URL and get an XML result if (is_null($resultDOM = $this->callWebService(PUBMED_WEBSERVICE_EFETCH, $lookupParams))) { return $nullVar; } $articleTitleNodes = $resultDOM->getElementsByTagName('ArticleTitle'); $articleTitleFirstNode = $articleTitleNodes->item(0); $medlineTaNodes = $resultDOM->getElementsByTagName('MedlineTA'); $medlineTaFirstNode = $medlineTaNodes->item(0); $metadata = array('pub-id[@pub-id-type="pmid"]' => $pmid, 'article-title' => $articleTitleFirstNode->textContent, 'source' => $medlineTaFirstNode->textContent); $volumeNodes = $resultDOM->getElementsByTagName('Volume'); $issueNodes = $resultDOM->getElementsByTagName('Issue'); if ($volumeNodes->length > 0) { $volumeFirstNode = $volumeNodes->item(0); } $metadata['volume'] = $volumeFirstNode->textContent; if ($issueNodes->length > 0) { $issueFirstNode = $issueNodes->item(0); } $metadata['issue'] = $issueFirstNode->textContent; // Get list of author full names foreach ($resultDOM->getElementsByTagName("Author") as $authorNode) { if (!isset($metadata['person-group[@person-group-type="author"]'])) { $metadata['person-group[@person-group-type="author"]'] = array(); } // Instantiate an NLM name description $authorDescription = new MetadataDescription('lib.pkp.plugins.metadata.nlm30.schema.Nlm30NameSchema', ASSOC_TYPE_AUTHOR); // Surname $lastNameNodes = $authorNode->getElementsByTagName('LastName'); $lastNameFirstNode = $lastNameNodes->item(0); $authorDescription->addStatement('surname', $lastNameFirstNode->textContent); // Given names $givenNamesString = ''; $firstNameNodes = $authorNode->getElementsByTagName('FirstName'); if ($firstNameNodes->length > 0) { $firstNameFirstNode = $firstNameNodes->item(0); $givenNamesString = $firstNameFirstNode->textContent; } else { $foreNameNodes = $authorNode->getElementsByTagName('ForeName'); if ($foreNameNodes->length > 0) { $foreNameFirstNode = $foreNameNodes->item(0); $givenNamesString = $foreNameFirstNode->textContent; } } if (!empty($givenNamesString)) { foreach (explode(' ', $givenNamesString) as $givenName) { $authorDescription->addStatement('given-names', PKPString::trimPunctuation($givenName)); } } // Suffix $suffixNodes = $authorNode->getElementsByTagName('Suffix'); if ($suffixNodes->length > 0) { $suffixFirstNode = $suffixNodes->item(0); $authorDescription->addStatement('suffix', $suffixFirstNode->textContent); } // Include collective names // FIXME: This corresponds to an NLM-citation <collab> tag and should be part of the Metadata implementation /*if ($resultDOM->getElementsByTagName("CollectiveName")->length > 0 && $authorNode->getElementsByTagName("CollectiveName")->item(0)->textContent != '') { }*/ $metadata['person-group[@person-group-type="author"]'][] =& $authorDescription; unset($authorDescription); } // Extract pagination $medlinePgnNodes = $resultDOM->getElementsByTagName('MedlinePgn'); $medlinePgnFirstNode = $medlinePgnNodes->item(0); if (PKPString::regexp_match_get("/^[:p\\.\\s]*(?P<fpage>[Ee]?\\d+)(-(?P<lpage>\\d+))?/", $medlinePgnFirstNode->textContent, $pages)) { $fPage = (int) $pages['fpage']; $metadata['fpage'] = $fPage; if (!empty($pages['lpage'])) { $lPage = (int) $pages['lpage']; // Deal with shortcuts like '382-7' if ($lPage < $fPage) { $lPage = (int) (PKPString::substr($pages['fpage'], 0, -PKPString::strlen($pages['lpage'])) . $pages['lpage']); } $metadata['lpage'] = $lPage; } } // Get publication date (can be in several places in PubMed). $dateNode = null; $articleDateNodes = $resultDOM->getElementsByTagName('ArticleDate'); if ($articleDateNodes->length > 0) { $dateNode = $articleDateNodes->item(0); } else { $pubDateNodes = $resultDOM->getElementsByTagName('PubDate'); if ($pubDateNodes->length > 0) { $dateNode = $pubDateNodes->item(0); } } // Retrieve the data parts and assemble date. if (!is_null($dateNode)) { $publicationDate = ''; $requiresNormalization = false; foreach (array('Year' => 4, 'Month' => 2, 'Day' => 2) as $dateElement => $padding) { $dateElementNodes = $dateNode->getElementsByTagName($dateElement); if ($dateElementNodes->length > 0) { if (!empty($publicationDate)) { $publicationDate .= '-'; } $dateElementFirstNode = $dateElementNodes->item(0); $datePart = str_pad($dateElementFirstNode->textContent, $padding, '0', STR_PAD_LEFT); if (!is_numeric($datePart)) { $requiresNormalization = true; } $publicationDate .= $datePart; } else { break; } } // Normalize the date to NLM standard if necessary. if ($requiresNormalization) { $dateFilter = new DateStringNormalizerFilter(); $publicationDate = $dateFilter->execute($publicationDate); } if (!empty($publicationDate)) { $metadata['date'] = $publicationDate; } } // Get publication type $publicationTypeNodes = $resultDOM->getElementsByTagName('PublicationType'); if ($publicationTypeNodes->length > 0) { foreach ($publicationTypeNodes as $publicationType) { // The vast majority of items on PubMed are articles so catch these... if (PKPString::strpos(PKPString::strtolower($publicationType->textContent), 'article') !== false) { $metadata['[@publication-type]'] = NLM30_PUBLICATION_TYPE_JOURNAL; break; } } } // Get DOI if it exists $articleIdNodes = $resultDOM->getElementsByTagName('ArticleId'); foreach ($articleIdNodes as $idNode) { if ($idNode->getAttribute('IdType') == 'doi') { $metadata['pub-id[@pub-id-type="doi"]'] = $idNode->textContent; } } // Use eLink utility to find fulltext links $lookupParams = array('dbfrom' => 'pubmed', 'cmd' => 'llinks', 'tool' => 'pkp-wal', 'id' => $pmid); if (!is_null($resultDOM = $this->callWebService(PUBMED_WEBSERVICE_ELINK, $lookupParams))) { // Get a list of possible links foreach ($resultDOM->getElementsByTagName("ObjUrl") as $linkOut) { $attributes = ''; foreach ($linkOut->getElementsByTagName("Attribute") as $attribute) { $attributes .= PKPString::strtolower($attribute->textContent) . ' / '; } // Only add links to open access resources if (PKPString::strpos($attributes, "subscription") === false && PKPString::strpos($attributes, "membership") === false && PKPString::strpos($attributes, "fee") === false && $attributes != "") { $urlNodes = $linkOut->getElementsByTagName('Url'); $urlFirstNode = $urlNodes->item(0); $links[] = $urlFirstNode->textContent; } } // Take the first link if we have any left (presumably pubmed returns them in preferential order) if (isset($links[0])) { $metadata['uri'] = $links[0]; } } return $this->getNlm30CitationDescriptionFromMetadataArray($metadata); }
/** * Retrieve auto-suggestions from the faceting service. * @param $url string * @param $searchRequest SolrSearchRequest * @param $userInput string * @param $fieldName string * @return array The generated suggestions. */ function _getFacetingAutosuggestions($url, $searchRequest, $userInput, $fieldName) { // Remove special characters from the user input. $searchTerms = strtr($userInput, '"()+-|&!', ' '); // Cut off the last search term. $searchTerms = explode(' ', $searchTerms); $facetPrefix = array_pop($searchTerms); if (empty($facetPrefix)) { return array(); } // Use the remaining search query to pre-filter // facet results. This may be an invalid query // but edismax will deal gracefully with syntax // errors. $userInput = PKPString::substr($userInput, 0, -PKPString::strlen($facetPrefix)); switch ($fieldName) { case 'query': // The 'query' filter goes against all fields. $articleSearch = new ArticleSearch(); $solrFields = array_values($articleSearch->getIndexFieldMap()); break; case 'indexTerms': // The 'index terms' filter goes against keyword index fields. $solrFields = array('discipline', 'subject', 'type', 'coverage'); break; default: // All other filters can be used directly. $solrFields = array($fieldName); } $solrFieldString = implode('|', $solrFields); $searchRequest->addQueryFieldPhrase($solrFieldString, $userInput); // Construct the main query. $params = $this->_getSearchQueryParameters($searchRequest); if (!isset($params['q'])) { // Use a catch-all query in case we have no limiting // search. $params['q'] = '*:*'; } if ($fieldName == 'query') { $params['facet.field'] = 'default_spell'; } else { $params['facet.field'] = $fieldName . '_spell'; } $facetPrefixLc = PKPString::strtolower($facetPrefix); $params['facet.prefix'] = $facetPrefixLc; // Make the request. $response = $this->_makeRequest($url, $params); if (!is_a($response, 'DOMXPath')) { return array(); } // Extract term suggestions. $nodeList = $response->query('//lst[@name="facet_fields"]/lst/int/@name'); if ($nodeList->length == 0) { return array(); } $termSuggestions = array(); foreach ($nodeList as $childNode) { $termSuggestions[] = $childNode->value; } // Add the term suggestion to the remaining user input. $suggestions = array(); foreach ($termSuggestions as $termSuggestion) { // Restore case if possible. if (strpos($termSuggestion, $facetPrefixLc) === 0) { $termSuggestion = $facetPrefix . PKPString::substr($termSuggestion, PKPString::strlen($facetPrefix)); } $suggestions[] = $userInput . $termSuggestion; } return $suggestions; }
/** * Subclasses can override this method to configure the * handler. * * NB: This method will be called after validation and * authorization. * * @param $request PKPRequest * @param $args array */ function initialize($request, $args = null) { // Set the controller id to the requested // page (page routing) or component name // (component routing) by default. $router = $request->getRouter(); if (is_a($router, 'PKPComponentRouter')) { $componentId = $router->getRequestedComponent($request); // Create a somewhat compressed but still globally unique // and human readable component id. // Example: "grid.citation.CitationGridHandler" // becomes "grid-citation-citationgrid" $componentId = str_replace('.', '-', PKPString::strtolower(PKPString::substr($componentId, 0, -7))); $this->setId($componentId); } else { assert(is_a($router, 'PKPPageRouter')); $this->setId($router->getRequestedPage($request)); } }
/** * Suggest a username given the first and last names. * @return string */ static function suggestUsername($firstName, $lastName) { $initial = PKPString::substr($firstName, 0, 1); $suggestion = PKPString::regexp_replace('/[^a-zA-Z0-9_-]/', '', PKPString::strtolower($initial . $lastName)); $userDao = DAORegistry::getDAO('UserDAO'); for ($i = ''; $userDao->userExistsByUsername($suggestion . $i); $i++) { } return $suggestion . $i; }
/** * @copydoc Filter::process() * @param $citationDescription MetadataDescription * @return MetadataDescription */ function &process(&$citationDescription) { $nullVar = null; $email = $this->getEmail(); assert(!empty($email)); $searchParams = array('pid' => $email, 'noredirect' => 'true', 'format' => 'unixref'); $doi = $citationDescription->getStatement('pub-id[@pub-id-type="doi"]'); if (!empty($doi)) { // Directly look up the DOI with OpenURL 0.1. $searchParams['id'] = 'doi:' . $doi; } else { // Use OpenURL meta-data to search for the entry. if (is_null($openurl10Metadata = $this->_prepareOpenurl10Search($citationDescription))) { return $nullVar; } $searchParams += $openurl10Metadata; } // Call the CrossRef web service if (is_null($resultXml =& $this->callWebService(CROSSREF_WEBSERVICE_URL, $searchParams, XSL_TRANSFORMER_DOCTYPE_STRING)) || PKPString::substr(trim($resultXml), 0, 6) == '<html>') { return $nullVar; } // Remove default name spaces from XML as CrossRef doesn't // set them reliably and element names are unique anyway. $resultXml = PKPString::regexp_replace('/ xmlns="[^"]+"/', '', $resultXml); // Transform and process the web service result if (is_null($metadata =& $this->transformWebServiceResults($resultXml, dirname(__FILE__) . DIRECTORY_SEPARATOR . 'crossref.xsl'))) { return $nullVar; } return $this->getNlm30CitationDescriptionFromMetadataArray($metadata); }
/** * Get initials. * @return string */ function getInitials() { $initials = $this->getData('initials'); if (!$initials) { $initials = PKPString::substr($this->getFirstName(), 0, 1) . PKPString::substr($this->getLastName(), 0, 1); } return $initials; }
/** * Set the submission data from the form. * @param $submission Submission */ function setSubmissionData($submission) { $this->submission->setLanguage(PKPString::substr($this->submission->getLocale(), 0, 2)); $this->submission->setCommentsToEditor($this->getData('commentsToEditor')); $this->submission->setLocale($this->getData('locale')); }
/** * Generate the DOM tree for a given article. * @param $doc object DOM object * @param $journal object Journal * @param $issue object Issue * @param $section object Section * @param $article object Article */ function &generateArticleDom(&$doc, &$journal, &$issue, &$section, &$article) { $root =& XMLCustomWriter::createElement($doc, 'record'); /* --- Article Language --- */ XMLCustomWriter::createChildWithText($doc, $root, 'language', DOAJExportDom::mapLang($article->getLanguage()), false); /* --- Publisher name (i.e. institution name) --- */ XMLCustomWriter::createChildWithText($doc, $root, 'publisher', $journal->getSetting('publisherInstitution'), false); /* --- Journal's title --- */ XMLCustomWriter::createChildWithText($doc, $root, 'journalTitle', $journal->getLocalizedName(), false); /* --- Identification Numbers --- */ XMLCustomWriter::createChildWithText($doc, $root, 'issn', $journal->getSetting('printIssn'), false); XMLCustomWriter::createChildWithText($doc, $root, 'eissn', $journal->getSetting('onlineIssn'), false); /* --- Article's publication date, volume, issue, DOI --- */ XMLCustomWriter::createChildWithText($doc, $root, 'publicationDate', DOAJExportDom::formatDate($article->getDatePublished()), false); XMLCustomWriter::createChildWithText($doc, $root, 'volume', $issue->getVolume(), false); XMLCustomWriter::createChildWithText($doc, $root, 'issue', $issue->getNumber(), false); /** --- FirstPage / LastPage (from PubMed plugin)--- * there is some ambiguity for online journals as to what * "page numbers" are; for example, some journals (eg. JMIR) * use the "e-location ID" as the "page numbers" in PubMed */ $pages = $article->getPages(); if (preg_match("/([0-9]+)\\s*-\\s*([0-9]+)/i", $pages, $matches)) { // simple pagination (eg. "pp. 3-8") XMLCustomWriter::createChildWithText($doc, $root, 'startPage', $matches[1]); XMLCustomWriter::createChildWithText($doc, $root, 'endPage', $matches[2]); } elseif (preg_match("/(e[0-9]+)/i", $pages, $matches)) { // elocation-id (eg. "e12") XMLCustomWriter::createChildWithText($doc, $root, 'startPage', $matches[1]); XMLCustomWriter::createChildWithText($doc, $root, 'endPage', $matches[1]); } XMLCustomWriter::createChildWithText($doc, $root, 'doi', $article->getPubId('doi'), false); /* --- Article's publication date, volume, issue, DOI --- */ XMLCustomWriter::createChildWithText($doc, $root, 'publisherRecordId', $article->getPublishedArticleId(), false); XMLCustomWriter::createChildWithText($doc, $root, 'documentType', $article->getLocalizedType(), false); /* --- Article title --- */ foreach ((array) $article->getTitle(null) as $locale => $title) { if (empty($title)) { continue; } $titleNode =& XMLCustomWriter::createChildWithText($doc, $root, 'title', $title); if (strlen($locale) == 5) { XMLCustomWriter::setAttribute($titleNode, 'language', DOAJExportDom::mapLang(PKPString::substr($locale, 0, 2))); } } /* --- Authors and affiliations --- */ $authors =& XMLCustomWriter::createElement($doc, 'authors'); XMLCustomWriter::appendChild($root, $authors); $affilList = DOAJExportDom::generateAffiliationsList($article->getAuthors()); foreach ($article->getAuthors() as $author) { $authorNode =& DOAJExportDom::generateAuthorDom($doc, $root, $issue, $article, $author, $affilList); XMLCustomWriter::appendChild($authors, $authorNode); unset($authorNode); } if (!empty($affilList[0])) { $affils =& XMLCustomWriter::createElement($doc, 'affiliationsList'); XMLCustomWriter::appendChild($root, $affils); for ($i = 0; $i < count($affilList); $i++) { $affilNode =& XMLCustomWriter::createChildWithText($doc, $affils, 'affiliationName', $affilList[$i]); XMLCustomWriter::setAttribute($affilNode, 'affiliationId', $i); unset($affilNode); } } /* --- Abstract --- */ foreach ((array) $article->getAbstract(null) as $locale => $abstract) { if (empty($abstract)) { continue; } $abstractNode =& XMLCustomWriter::createChildWithText($doc, $root, 'abstract', $abstract); if (strlen($locale) == 5) { XMLCustomWriter::setAttribute($abstractNode, 'language', DOAJExportDom::mapLang(PKPString::substr($locale, 0, 2))); } } /* --- FullText URL --- */ $fullTextUrl =& XMLCustomWriter::createChildWithText($doc, $root, 'fullTextUrl', Request::url(null, 'article', 'view', $article->getId())); XMLCustomWriter::setAttribute($fullTextUrl, 'format', 'html'); /* --- Keywords --- */ $keywords =& XMLCustomWriter::createElement($doc, 'keywords'); XMLCustomWriter::appendChild($root, $keywords); $subjects = array_map('trim', explode(';', $article->getLocalizedSubject())); foreach ($subjects as $keyword) { XMLCustomWriter::createChildWithText($doc, $keywords, 'keyword', $keyword, false); } return $root; }
/** * Parse an XML file using the specified handler. * If no handler has been specified, XMLParserDOMHandler is used by default, returning a tree structure representing the document. * @param $file string full path to the XML file * @param $dataCallback mixed Optional callback for data handling: function dataCallback($operation, $wrapper, $data = null) * @return object actual return type depends on the handler */ function &parse($file, $dataCallback = null) { $parser =& $this->createParser(); if (!isset($this->handler)) { // Use default handler for parsing $handler = new XMLParserDOMHandler(); $this->setHandler($handler); } xml_set_object($parser, $this->handler); xml_set_element_handler($parser, "startElement", "endElement"); xml_set_character_data_handler($parser, "characterData"); import('lib.pkp.classes.file.FileWrapper'); $wrapper =& FileWrapper::wrapper($file); // Handle responses of various types while (true) { $newWrapper = $wrapper->open(); if (is_object($newWrapper)) { // Follow a redirect unset($wrapper); $wrapper =& $newWrapper; unset($newWrapper); } elseif (!$newWrapper) { // Could not open resource -- error $returner = false; return $returner; } else { // OK, we've found the end result break; } } if (!$wrapper) { $result = false; return $result; } if ($dataCallback) { call_user_func($dataCallback, 'open', $wrapper); } while (!$wrapper->eof() && ($data = $wrapper->read()) !== false) { // if the string contains non-UTF8 characters, convert it to UTF-8 for parsing if (Config::getVar('i18n', 'charset_normalization') == 'On' && !PKPString::utf8_compliant($data)) { $utf8_last = PKPString::substr($data, PKPString::strlen($data) - 1); // if the string ends in a "bad" UTF-8 character, maybe it's truncated while (!$wrapper->eof() && PKPString::utf8_bad_find($utf8_last) === 0) { // read another chunk of data $data .= $wrapper->read(); $utf8_last = PKPString::substr($data, PKPString::strlen($data) - 1); } $data = PKPString::utf8_normalize($data); // strip any invalid UTF-8 sequences $data = PKPString::utf8_bad_strip($data); // convert named entities to numeric entities $data = strtr($data, PKPString::getHTMLEntities()); } // strip any invalid ASCII control characters $data = PKPString::utf8_strip_ascii_ctrl($data); if ($dataCallback) { call_user_func($dataCallback, 'parse', $wrapper, $data); } if (!xml_parse($parser, $data, $wrapper->eof())) { $this->addError(xml_error_string(xml_get_error_code($parser))); } } if ($dataCallback) { call_user_func($dataCallback, 'close', $wrapper); } $wrapper->close(); $result = $this->handler->getResult(); $this->destroyParser($parser); if (isset($handler)) { $handler->destroy(); } return $result; }
/** * @see PubIdPlugin::getResolvingURL() */ function getResolvingURL($journalId, $pubId) { // See ANSI/NISO Z39.84-2005, Appendix E. (Bug #8190) $separatorIndex = PKPString::strpos($pubId, '/'); assert($separatorIndex !== false); // Should contain a slash $prefix = PKPString::substr($pubId, 0, $separatorIndex); $suffix = PKPString::substr($pubId, $separatorIndex + 1); return 'http://dx.doi.org/' . $prefix . '/' . urlencode($suffix); }
/** * Truncate a filename to fit in the specified length. */ function truncateFileName($fileName, $length = 127) { if (PKPString::strlen($fileName) <= $length) { return $fileName; } $ext = $this->getExtension($fileName); $truncated = PKPString::substr($fileName, 0, $length - 1 - PKPString::strlen($ext)) . '.' . $ext; return PKPString::substr($truncated, 0, $length); }