/**
  * Generate and display the CAPTCHA image.
  * @param $captcha object Captcha
  */
 function generateImage(&$captcha)
 {
     $width = $this->getWidth();
     $height = $this->getHeight();
     $length = String::strlen($captcha->getValue());
     $value = $captcha->getValue();
     $image = imagecreatetruecolor($width, $height);
     $fg = imagecolorallocate($image, rand(128, 255), rand(128, 255), rand(128, 255));
     $bg = imagecolorallocate($image, rand(0, 64), rand(0, 64), rand(0, 64));
     imagefill($image, $width / 2, $height / 2, $bg);
     $xStart = rand($width / 12, $width / 3);
     $xEnd = rand($width * 2 / 3, $width * 11 / 12);
     for ($i = 0; $i < $length; $i++) {
         imagefttext($image, rand(20, 34), rand(-15, 15), $xStart + ($xEnd - $xStart) * $i / $length + rand(-5, 5), rand(40, 60), $fg, Config::getVar('captcha', 'font_location'), String::substr($value, $i, 1));
     }
     // Add some noise to the image.
     for ($i = 0; $i < 20; $i++) {
         $color = imagecolorallocate($image, rand(0, 255), rand(0, 255), rand(0, 255));
         for ($j = 0; $j < 20; $j++) {
             imagesetpixel($image, rand(0, $this->getWidth()), rand(0, $this->getHeight()), $color);
         }
     }
     header('Content-type: ' . $this->getMimeType());
     imagepng($image);
     imagedestroy($image);
 }
 /**
  * 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 = String::regexp_replace('/[!"\\#\\$%\'\\(\\)\\.\\?@\\[\\]\\^`\\{\\}~]/', '', $cleanText);
     $cleanText = String::regexp_replace('/[\\+,:;&\\/<=>\\|\\\\]/', ' ', $cleanText);
     $cleanText = String::regexp_replace('/[\\*]/', $allowWildcards ? '%' : ' ', $cleanText);
     $cleanText = String::strtolower($cleanText);
     // Split into words
     $words = String::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]) && String::strlen($k) >= $minLength && !is_numeric($k)) {
             $keywords[] = String::substr($k, 0, SEARCH_KEYWORD_MAX_LENGTH);
         }
     }
     return $keywords;
 }
示例#3
0
 /**
  * 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 - String::strlen($suffix) - 1);
     $baseName = String::substr($truncated, 0, String::strpos($originalFileName, $ext) - 1);
     // Try a simple syntax first
     $fileName = $baseName . '-' . $suffix . '.' . $ext;
     if (!$libraryFileDao->filenameExists($this->pressId, $fileName)) {
         return $fileName;
     }
     for ($i = 1;; $i++) {
         $fullSuffix = $suffix . '-' . $i;
         //truncate more if necessary
         $truncated = $this->truncateFileName($originalFileName, 127 - String::strlen($fullSuffix) - 1);
         // get the base name and append the suffix
         $baseName = String::substr($truncated, 0, String::strpos($originalFileName, $ext) - 1);
         //try the following
         $fileName = $baseName . '-' . $fullSuffix . '.' . $ext;
         if (!$libraryFileDao->filenameExists($this->pressId, $fileName)) {
             return $fileName;
         }
     }
 }
 /**
  * @see FormValidator::isValid()
  * Value is valid if it is empty and optional or meets the specified length requirements.
  * @return boolean
  */
 function isValid()
 {
     if ($this->isEmptyAndOptional()) {
         return true;
     } else {
         $length = String::strlen($this->getFieldValue());
         switch ($this->_comparator) {
             case '==':
                 return $length == $this->_length;
             case '!=':
                 return $length != $this->_length;
             case '<':
                 return $length < $this->_length;
             case '>':
                 return $length > $this->_length;
             case '<=':
                 return $length <= $this->_length;
             case '>=':
                 return $length >= $this->_length;
         }
         return false;
     }
 }
示例#5
0
 /**
  * Check if field value is valid.
  * Value is valid if it is empty and optional or meets the specified length requirements.
  * @return boolean
  */
 function isValid()
 {
     if ($this->isEmptyAndOptional()) {
         return true;
     } else {
         $length = String::strlen(trim($this->form->getData($this->field)));
         switch ($this->comparator) {
             case '==':
                 return $length == $this->length;
             case '!=':
                 return $length != $this->length;
             case '<':
                 return $length < $this->length;
             case '>':
                 return $length > $this->length;
             case '<=':
                 return $length <= $this->length;
             case '>=':
                 return $length >= $this->length;
         }
         return false;
     }
 }
示例#6
0
 /**
  * Truncate a filename to fit in the specified length.
  */
 function truncateFileName($fileName, $length = 127)
 {
     if (String::strlen($fileName) <= $length) {
         return $fileName;
     }
     $ext = $this->getExtension($fileName);
     $truncated = String::substr($fileName, 0, $length - 1 - String::strlen($ext)) . '.' . $ext;
     return String::substr($truncated, 0, $length);
 }
示例#7
0
 /**
  * 格式化字段
  * 
  * @access private
  * @param mixed $typeInfo
  * @param mixed $value
  * @return mixed
  */
 private function formatField($typeInfo, $value)
 {
     preg_match("/(\\w+)(\\((\\d+)\\))?/", $typeInfo, $matches);
     if (isset($matches[1])) {
         $type = $matches[1];
     }
     if (isset($matches[3])) {
         $len = $matches[3];
     }
     $_type = "string";
     $type = strtolower($type);
     switch ($type) {
         case 'bit':
         case 'bigbit':
         case 'bool':
         case 'boolean':
         case 'decimal':
         case 'decimal':
         case 'dec':
         case 'double':
         case 'float':
         case 'int':
         case 'bigint':
         case 'mediumint':
         case 'smallint':
         case 'tinyint':
         case 'real':
             if (!is_numeric($value)) {
                 $value = 0;
             }
             if ($value == '' || $value == null || empty($value)) {
                 $value = 0;
             }
             $_type = 'numeric';
             break;
     }
     if (isset($len)) {
         if (!is_array($value) && String::strlen($value) > $len) {
             $value = String::msubstr($value, 0, $len, 'utf-8', '');
         }
     }
     if (is_array($value)) {
         $value = serialize($value);
     }
     if ($_type == 'string') {
         $value = '\'' . $value . '\'';
     }
     return $value;
 }
示例#8
0
 /**
  * Calculate the differences between two strings and
  * produce an array with three types of entries: added
  * substrings, deleted substrings and unchanged substrings.
  *
  * The calculation is optimized to identify the common
  * largest substring.
  *
  * The return value is an array of the following format:
  *
  * array(
  *   array( diff-type => substring ),
  *   array(...)
  * )
  *
  * whereby diff-type can be one of:
  *   -1 = deletion
  *    0 = common substring
  *    1 = addition
  *
  * @param $originalString string
  * @param $editedString string
  * @return array
  */
 static function diff($originalString, $editedString)
 {
     // Split strings into character arrays (multi-byte compatible).
     foreach (array('originalStringCharacters' => $originalString, 'editedStringCharacters' => $editedString) as $characterArrayName => $string) {
         ${$characterArrayName} = array();
         String::regexp_match_all('/./', $string, ${$characterArrayName});
         if (isset(${$characterArrayName}[0])) {
             ${$characterArrayName} = ${$characterArrayName}[0];
         }
     }
     // Determine the length of the strings.
     $originalStringLength = count($originalStringCharacters);
     $editedStringLength = count($editedStringCharacters);
     // Is there anything to compare?
     if ($originalStringLength == 0 && $editedStringLength == 0) {
         return array();
     }
     // Is the original string empty?
     if ($originalStringLength == 0) {
         // Return the edited string as addition.
         return array(array(1 => $editedString));
     }
     // Is the edited string empty?
     if ($editedStringLength == 0) {
         // Return the original string as deletion.
         return array(array(-1 => $originalString));
     }
     // Initialize the local indices:
     // 1) Create a character index for the edited string.
     $characterIndex = array();
     for ($characterPosition = 0; $characterPosition < $editedStringLength; $characterPosition++) {
         $characterIndex[$editedStringCharacters[$characterPosition]][] = $characterPosition;
     }
     // 2) Initialize the substring and the length index.
     $substringIndex = $lengthIndex = array();
     // Iterate over the original string to identify
     // the largest common string.
     for ($originalPosition = 0; $originalPosition < $originalStringLength; $originalPosition++) {
         // Find all occurrences of the original character
         // in the target string.
         $comparedCharacter = $originalStringCharacters[$originalPosition];
         // Do we have a commonality between the original string
         // and the edited string?
         if (isset($characterIndex[$comparedCharacter])) {
             // Loop over all commonalities.
             foreach ($characterIndex[$comparedCharacter] as $editedPosition) {
                 // Calculate the current and the preceding position
                 // ids for indexation.
                 $currentPosition = $originalPosition . '-' . $editedPosition;
                 $previousPosition = $originalPosition - 1 . '-' . ($editedPosition - 1);
                 // Does the occurrence in the target string continue
                 // an existing common substring or does it start
                 // a new one?
                 if (isset($substringIndex[$previousPosition])) {
                     // This is a continuation of an existing common
                     // substring...
                     $newSubstring = $substringIndex[$previousPosition] . $comparedCharacter;
                     $newSubstringLength = String::strlen($newSubstring);
                     // Move the substring in the substring index.
                     $substringIndex[$currentPosition] = $newSubstring;
                     unset($substringIndex[$previousPosition]);
                     // Move the substring in the length index.
                     $lengthIndex[$newSubstringLength][$currentPosition] = $newSubstring;
                     unset($lengthIndex[$newSubstringLength - 1][$previousPosition]);
                 } else {
                     // Start a new common substring...
                     // Add the substring to the substring index.
                     $substringIndex[$currentPosition] = $comparedCharacter;
                     // Add the substring to the length index.
                     $lengthIndex[1][$currentPosition] = $comparedCharacter;
                 }
             }
         }
     }
     // If we have no commonalities at all then mark the original
     // string as deleted and the edited string as added and
     // return.
     if (empty($lengthIndex)) {
         return array(array(-1 => $originalString), array(1 => $editedString));
     }
     // Pop the largest common substrings from the length index.
     end($lengthIndex);
     $largestSubstringLength = key($lengthIndex);
     // Take the first common substring if we have more than
     // one substring with the same length.
     // FIXME: Find a better heuristic for this decision.
     reset($lengthIndex[$largestSubstringLength]);
     $largestSubstringPosition = key($lengthIndex[$largestSubstringLength]);
     list($largestSubstringEndOriginal, $largestSubstringEndEdited) = explode('-', $largestSubstringPosition);
     $largestSubstring = $lengthIndex[$largestSubstringLength][$largestSubstringPosition];
     // Add the largest common substring to the result set
     $diffResult = array(array(0 => $largestSubstring));
     // Prepend the diff of the substrings before the common substring
     // to the result diff (by recursion).
     $precedingSubstringOriginal = String::substr($originalString, 0, $largestSubstringEndOriginal - $largestSubstringLength + 1);
     $precedingSubstringEdited = String::substr($editedString, 0, $largestSubstringEndEdited - $largestSubstringLength + 1);
     $diffResult = array_merge(String::diff($precedingSubstringOriginal, $precedingSubstringEdited), $diffResult);
     // Append the diff of the substrings after thr common substring
     // to the result diff (by recursion).
     $succeedingSubstringOriginal = String::substr($originalString, $largestSubstringEndOriginal + 1);
     $succeedingSubstringEdited = String::substr($editedString, $largestSubstringEndEdited + 1);
     $diffResult = array_merge($diffResult, String::diff($succeedingSubstringOriginal, $succeedingSubstringEdited));
     // Return the array representing the diff.
     return $diffResult;
 }
 /**
  * Fills the given citation object with
  * meta-data retrieved from PubMed.
  * @param $pmid string
  * @param $citationDescription MetadataDescription
  * @return MetadataDescription
  */
 function &_lookup($pmid, &$citationDescription)
 {
     $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;
     }
     $metadata = array('pub-id[@pub-id-type="pmid"]' => $pmid, 'article-title' => $resultDOM->getElementsByTagName("ArticleTitle")->item(0)->textContent, 'source' => $resultDOM->getElementsByTagName("MedlineTA")->item(0)->textContent);
     if ($resultDOM->getElementsByTagName("Volume")->length > 0) {
         $metadata['volume'] = $resultDOM->getElementsByTagName("Volume")->item(0)->textContent;
     }
     if ($resultDOM->getElementsByTagName("Issue")->length > 0) {
         $metadata['issue'] = $resultDOM->getElementsByTagName("Issue")->item(0)->textContent;
     }
     // get list of author full names
     $nlmNameSchema = new NlmNameSchema();
     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($nlmNameSchema, ASSOC_TYPE_AUTHOR);
         // Surname
         $authorDescription->addStatement('surname', $authorNode->getElementsByTagName("LastName")->item(0)->textContent);
         // Given names
         $givenNamesString = '';
         if ($authorNode->getElementsByTagName("FirstName")->length > 0) {
             $givenNamesString = $authorNode->getElementsByTagName("FirstName")->item(0)->textContent;
         } elseif ($authorNode->getElementsByTagName("ForeName")->length > 0) {
             $givenNamesString = $authorNode->getElementsByTagName("ForeName")->item(0)->textContent;
         }
         if (!empty($givenNamesString)) {
             foreach (explode(' ', $givenNamesString) as $givenName) {
                 $authorDescription->addStatement('given-names', String::trimPunctuation($givenName));
             }
         }
         // Suffix
         if ($authorNode->getElementsByTagName("Suffix")->length > 0) {
             $authorDescription->addStatement('suffix', $authorNode->getElementsByTagName("Suffix")->item(0)->textContent);
         }
         // Include collective names
         /*if ($resultDOM->getElementsByTagName("CollectiveName")->length > 0 && $authorNode->getElementsByTagName("CollectiveName")->item(0)->textContent != '') {
         			// FIXME: This corresponds to an NLM-citation <collab> tag and should be part of the Metadata implementation
         		}*/
         $metadata['person-group[@person-group-type="author"]'][] =& $authorDescription;
         unset($authorDescription);
     }
     // Extract pagination
     if (String::regexp_match_get("/^[:p\\.\\s]*(?P<fpage>[Ee]?\\d+)(-(?P<lpage>\\d+))?/", $resultDOM->getElementsByTagName("MedlinePgn")->item(0)->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) (String::substr($pages['fpage'], 0, -String::strlen($pages['lpage'])) . $pages['lpage']);
             }
             $metadata['lpage'] = $lPage;
         }
     }
     // Get publication date
     // TODO: The publication date could be in multiple places
     if ($resultDOM->getElementsByTagName("ArticleDate")->length > 0) {
         $publicationDate = $resultDOM->getElementsByTagName("ArticleDate")->item(0)->getElementsByTagName("Year")->item(0)->textContent . '-' . $resultDOM->getElementsByTagName("ArticleDate")->item(0)->getElementsByTagName("Month")->item(0)->textContent . '-' . $resultDOM->getElementsByTagName("ArticleDate")->item(0)->getElementsByTagName("Day")->item(0)->textContent;
         $metadata['date'] = $publicationDate;
     }
     // Get publication type
     if ($resultDOM->getElementsByTagName("PublicationType")->length > 0) {
         foreach ($resultDOM->getElementsByTagName("PublicationType") as $publicationType) {
             // The vast majority of items on PubMed are articles so catch these...
             if (String::strpos(String::strtolower($publicationType->textContent), 'article') !== false) {
                 $metadata['[@publication-type]'] = NLM_PUBLICATION_TYPE_JOURNAL;
                 break;
             }
         }
     }
     // Get DOI if it exists
     foreach ($resultDOM->getElementsByTagName("ArticleId") 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 .= String::strtolower($attribute->textContent) . ' / ';
             }
             // Only add links to open access resources
             if (String::strpos($attributes, "subscription") === false && String::strpos($attributes, "membership") === false && String::strpos($attributes, "fee") === false && $attributes != "") {
                 $links[] = $linkOut->getElementsByTagName("Url")->item(0)->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->addMetadataArrayToNlmCitationDescription($metadata, $citationDescription);
 }
示例#10
0
 /**
  * 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 = String::substr($userInput, 0, -String::strlen($facetPrefix));
     switch ($fieldName) {
         case 'query':
             // The 'query' filter goes agains 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 = String::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 . String::substr($termSuggestion, String::strlen($facetPrefix));
         }
         $suggestions[] = $userInput . $termSuggestion;
     }
     return $suggestions;
 }
 /**
  * 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
  * @return object actual return type depends on the handler
  */
 function &parse($file)
 {
     $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;
     }
     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' && !String::utf8_compliant($data)) {
             $utf8_last = String::substr($data, String::strlen($data) - 1);
             // if the string ends in a "bad" UTF-8 character, maybe it's truncated
             while (!$wrapper->eof() && String::utf8_bad_find($utf8_last) === 0) {
                 // read another chunk of data
                 $data .= $wrapper->read();
                 $utf8_last = String::substr($data, String::strlen($data) - 1);
             }
             $data = String::utf8_normalize($data);
             // strip any invalid UTF-8 sequences
             $data = String::utf8_bad_strip($data);
             // convert named entities to numeric entities
             $data = strtr($data, String::getHTMLEntities());
         }
         // strip any invalid ASCII control characters
         $data = String::utf8_strip_ascii_ctrl($data);
         if (!xml_parse($parser, $data, $wrapper->eof())) {
             $this->addError(xml_error_string(xml_get_error_code($parser)));
         }
     }
     $wrapper->close();
     $result =& $this->handler->getResult();
     $this->destroyParser($parser);
     if (isset($handler)) {
         $handler->destroy();
         unset($handler);
     }
     return $result;
 }
示例#12
0
 function mb_substr_replace($string, $replacement, $start, $length = null)
 {
     if (extension_loaded('mbstring') === true) {
         $string_length = String::strlen($string);
         if ($start < 0) {
             $start = max(0, $string_length + $start);
         } else {
             if ($start > $string_length) {
                 $start = $string_length;
             }
         }
         if ($length < 0) {
             $length = max(0, $string_length - $start + $length);
         } else {
             if (is_null($length) === true || $length > $string_length) {
                 $length = $string_length;
             }
         }
         if ($start + $length > $string_length) {
             $length = $string_length - $start;
         }
         return String::substr($string, 0, $start) . $replacement . String::substr($string, $start + $length, $string_length - $start - $length);
     }
 }
 /**
  * @function abntDateFormatWithDay Format date taking in consideration ABNT month abbreviations
  * @param $string string
  * @return string
  */
 function abntDateFormatWithDay($string)
 {
     if (is_numeric($string)) {
         // it is a numeric string, we handle it as timestamp
         $timestamp = (int) $string;
     } else {
         $timestamp = strtotime($string);
     }
     $format = "%d %B %Y";
     if (String::strlen(strftime("%B", $timestamp)) > 4) {
         $format = "%d %b. %Y";
     }
     return String::strtolower(strftime($format, $timestamp));
 }
示例#14
0
<?php

class String
{
    private $_string;
    public function __construct($string)
    {
        $this->_string = $string;
    }
    public function __call($method, $arguments)
    {
        $this->_string = call_user_func($method, $this->_string);
        return $this;
    }
    public function getValue()
    {
        return $this->_string;
    }
}
$test = new String('  test, test2 ');
$test->trim();
var_dump($test->getValue());
$test->strlen();
var_dump($test->getValue());
示例#15
0
 /**
  * Override the built-in smarty truncate modifier to support mbstring
  * text properly, if possible.
  */
 function smartyTruncate($string, $length = 80, $etc = '...', $break_words = false, $middle = false)
 {
     // Re-implement Smarty version, with multibyte-capable calls.
     if ($length == 0) {
         return '';
     }
     if (String::strlen($string) > $length) {
         $length -= min($length, String::strlen($etc));
         if (!$break_words && !$middle) {
             $string = String::regexp_replace('/\\s+?(\\S+)?$/', '', substr($string, 0, $length + 1));
         }
         if (!$middle) {
             return String::substr($string, 0, $length) . $etc;
         } else {
             return String::substr($string, 0, $length / 2) . $etc . String::substr($string, -$length / 2);
         }
     } else {
         return $string;
     }
 }
 /**
  * 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 = String::strlen($year) > 4 ? String::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('String', 'trimPunctuation'), $searchStrings);
     $searchStrings = array_unique($searchStrings);
     $searchStrings = arrayClean($searchStrings);
     return $searchStrings;
 }
 /**
  * Checks whether the given string is an ISBN.
  * @param $isbn
  * @return boolean
  */
 function isValidIsbn($isbn)
 {
     return is_string($isbn) && is_numeric($isbn) && String::strlen($isbn) == 13;
 }
 /**
  * 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', String::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 (String::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) (String::substr($pages['fpage'], 0, -String::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 (String::strpos(String::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 .= String::strtolower($attribute->textContent) . ' / ';
             }
             // Only add links to open access resources
             if (String::strpos($attributes, "subscription") === false && String::strpos($attributes, "membership") === false && String::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);
 }
示例#19
0
 function parseDate($fieldName, $value, $attributes = null)
 {
     switch ($fieldName) {
         case '005':
             // YYYYMMDDHHMMSS.0 Date and time of latest transaction
             if (String::strlen($value) < 14) {
                 return null;
             }
             $year = String::substr($value, 0, 4);
             $month = String::substr($value, 4, 2);
             $day = String::substr($value, 6, 2);
             $hour = String::substr($value, 8, 2);
             $minute = String::substr($value, 10, 2);
             $second = String::substr($value, 12);
             // Make sure the values fetched are all numeric
             foreach (array('year', 'month', 'day', 'hour', 'minute', 'second') as $var) {
                 if (!is_numeric(${$var})) {
                     return null;
                 }
             }
             return mktime($hour, $minute, $second, $month, $day, $year);
         case '008':
             // YYMMDD[junk] Date entered on file
             $date = String::substr($value, 0, 6);
             $date = strtotime($date);
             if ($date !== -1 && $date !== false) {
                 return $date;
             }
             break;
         case '260':
             if (isset($attributes['label']) && $attributes['label'] == 'c') {
                 $date = strtotime($value);
                 if ($date !== -1 && $date !== false) {
                     return $date;
                 }
             }
             break;
     }
     return null;
 }
 /**
  * Get the localized, truncated description of the book for review.
  * @return string
  */
 function getLocalizedDescriptionShort()
 {
     $end = '';
     if (String::strlen($this->getLocalizedData('description'))) {
         $end = ' ...';
     }
     return String::substr($this->getLocalizedData('description'), 0, 250) . $end;
 }
 /**
  * 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
  * @return string
  */
 function _flattenPersonDescription(&$personDescription)
 {
     $nameVars['%surname%'] = (string) $personDescription->getStatement('surname');
     $givenNames = $personDescription->getStatement('given-names');
     $nameVars['%firstname%'] = $nameVars['%initials%'] = '';
     if (is_array($givenNames) && count($givenNames)) {
         if (String::strlen($givenNames[0]) > 1) {
             $nameVars['%firstname%'] = array_shift($givenNames);
         }
         foreach ($givenNames as $givenName) {
             $nameVars['%initials%'] .= String::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;
 }
 /**
  * Converts a string with a single person
  * to an NLM name description.
  *
  * TODO: add initials from all given names to initials
  *       element
  *
  * @param $personString string
  * @param $title boolean true to parse for title
  * @param $degrees boolean true to parse for degrees
  * @return MetadataDescription an NLM name description or null
  *  if the string could not be converted
  */
 function &_parsePersonString($personString, $title, $degrees)
 {
     // Expressions to parse person strings, ported from CiteULike person
     // plugin, see http://svn.citeulike.org/svn/plugins/person.tcl
     static $personRegex = array('title' => '(?:His (?:Excellency|Honou?r)\\s+|Her (?:Excellency|Honou?r)\\s+|The Right Honou?rable\\s+|The Honou?rable\\s+|Right Honou?rable\\s+|The Rt\\.? Hon\\.?\\s+|The Hon\\.?\\s+|Rt\\.? Hon\\.?\\s+|Mr\\.?\\s+|Ms\\.?\\s+|M\\/s\\.?\\s+|Mrs\\.?\\s+|Miss\\.?\\s+|Dr\\.?\\s+|Sir\\s+|Dame\\s+|Prof\\.?\\s+|Professor\\s+|Doctor\\s+|Mister\\s+|Mme\\.?\\s+|Mast(?:\\.|er)?\\s+|Lord\\s+|Lady\\s+|Madam(?:e)?\\s+|Priv\\.-Doz\\.\\s+)+', 'degrees' => '(,\\s+(?:[A-Z\\.]+))+', 'initials' => '(?:(?:[A-Z]\\.){1,3}[A-Z]\\.?)|(?:(?:[A-Z]\\.\\s){1,3}[A-Z]\\.?)|(?:[A-Z]{1,4})|(?:(?:[A-Z]\\.-?){1,4})|(?:(?:[A-Z]\\.-?){1,3}[A-Z]\\.?)|(?:(?:[A-Z]-){1,3}[A-Z])|(?:(?:[A-Z]\\s){1,3}[A-Z]\\.?)|(?:(?:[A-Z]-){1,3}[A-Z]\\.?)', 'prefix' => 'Dell(?:[a|e])?(?:\\s|$)|Dalle(?:\\s|$)|D[a|e]ll\'(?:\\s|$)|Dela(?:\\s|$)|Del(?:\\s|$)|[Dd]e(?:\\s|$)(?:La(?:\\s|$)|Los(?:\\s|$))?|[Dd]e(?:\\s|$)|[Dd][a|i|u](?:\\s|$)|L[a|e|o](?:\\s|$)|[D|L|O]\'|St\\.?(?:\\s|$)|San(?:\\s|$)|[Dd]en(?:\\s|$)|[Vv]on(?:\\s|$)(?:[Dd]er(?:\\s|$))?|(?:[Ll][ea](?:\\s|$))?[Vv]an(?:\\s|$)(?:[Dd]e(?:n|r)?(?:\\s|$))?', 'givenName' => '(?:[^ \\t\\n\\r\\f\\v,.;()]{2,}|[^ \\t\\n\\r\\f\\v,.;()]{2,}\\-[^ \\t\\n\\r\\f\\v,.;()]{2,})');
     // The expressions for given name, suffix and surname are the same
     $personRegex['surname'] = $personRegex['suffix'] = $personRegex['givenName'];
     $personRegex['double-surname'] = "(?:" . $personRegex['surname'] . "\\s)*" . $personRegex['surname'];
     // Shortcut for prefixed surname
     $personRegexPrefixedSurname = "(?P<prefix>(?:" . $personRegex['prefix'] . ")?)(?P<surname>" . $personRegex['surname'] . ")";
     $personRegexPrefixedDoubleSurname = "(?P<prefix>(?:" . $personRegex['prefix'] . ")?)(?P<surname>" . $personRegex['double-surname'] . ")";
     // Instantiate the target person description
     $personDescription = new MetadataDescription('lib.pkp.plugins.metadata.nlm30.schema.Nlm30NameSchema', $this->_assocType);
     // Clean the person string
     $personString = trim($personString);
     // 1. Extract title and degree from the person string and use this as suffix
     $suffixString = '';
     $results = array();
     if ($title && String::regexp_match_get('/^(' . $personRegex['title'] . ')/i', $personString, $results)) {
         $suffixString = trim($results[1], ',:; ');
         $personString = String::regexp_replace('/^(' . $personRegex['title'] . ')/i', '', $personString);
     }
     if ($degrees && String::regexp_match_get('/(' . $personRegex['degrees'] . ')$/i', $personString, $results)) {
         $degreesArray = explode(',', trim($results[1], ','));
         foreach ($degreesArray as $key => $degree) {
             $degreesArray[$key] = String::trimPunctuation($degree);
         }
         $suffixString .= ' - ' . implode('; ', $degreesArray);
         $personString = String::regexp_replace('/(' . $personRegex['degrees'] . ')$/i', '', $personString);
     }
     if (!empty($suffixString)) {
         $personDescription->addStatement('suffix', $suffixString);
     }
     // Space initials when followed by a given name or last name.
     $personString = String::regexp_replace('/([A-Z])\\.([A-Z][a-z])/', '\\1. \\2', $personString);
     // 2. Extract names and initials from the person string
     // The parser expressions are ordered by specificity. The most specific expressions
     // come first. Only if these specific expressions don't work will we turn to less
     // specific ones. This avoids parsing errors. It also explains why we don't use the
     // ?-quantifier for optional elements like initials or middle name where they could
     // be misinterpreted.
     $personExpressions = array('/^' . $personRegexPrefixedSurname . '$/i', '/^(?P<initials>' . $personRegex['initials'] . ')\\s' . $personRegexPrefixedSurname . '$/', '/^' . $personRegexPrefixedSurname . ',?\\s(?P<initials>' . $personRegex['initials'] . ')$/', '/^' . $personRegexPrefixedDoubleSurname . ',\\s(?P<givenName>' . $personRegex['givenName'] . ')\\s(?P<initials>' . $personRegex['initials'] . ')$/', '/^(?P<givenName>' . $personRegex['givenName'] . ')\\s(?P<initials>' . $personRegex['initials'] . ')\\s' . $personRegexPrefixedSurname . '$/', '/^' . $personRegexPrefixedDoubleSurname . ',\\s(?P<givenName>(?:' . $personRegex['givenName'] . '\\s)+)(?P<initials>' . $personRegex['initials'] . ')$/', '/^(?P<givenName>(?:' . $personRegex['givenName'] . '\\s)+)(?P<initials>' . $personRegex['initials'] . ')\\s' . $personRegexPrefixedSurname . '$/', '/^' . $personRegexPrefixedDoubleSurname . ',(?P<givenName>(?:\\s' . $personRegex['givenName'] . ')+)$/', '/^(?P<givenName>(?:' . $personRegex['givenName'] . '\\s)+)' . $personRegexPrefixedSurname . '$/', '/^\\s*(?P<surname>' . $personRegex['surname'] . ')(?P<suffix>(?:\\s+' . $personRegex['suffix'] . ')?)\\s*,\\s*(?P<initials>(?:' . $personRegex['initials'] . ')?)\\s*\\((?P<givenName>(?:\\s*' . $personRegex['givenName'] . ')+)\\s*\\)\\s*(?P<prefix>(?:' . $personRegex['prefix'] . ')?)$/', '/^(?P<givenName>' . $personRegex['givenName'] . ')\\.(?P<surname>' . $personRegex['double-surname'] . ')$/', '/^(?P<surname>.*)$/');
     $results = array();
     foreach ($personExpressions as $expressionId => $personExpression) {
         if ($nameFound = String::regexp_match_get($personExpression, $personString, $results)) {
             // Given names
             if (!empty($results['givenName'])) {
                 // Split given names
                 $givenNames = explode(' ', trim($results['givenName']));
                 foreach ($givenNames as $givenName) {
                     $personDescription->addStatement('given-names', $givenName);
                     unset($givenName);
                 }
             }
             // Initials (will also be saved as given names)
             if (!empty($results['initials'])) {
                 $results['initials'] = str_replace(array('.', '-', ' '), array('', '', ''), $results['initials']);
                 for ($initialNum = 0; $initialNum < String::strlen($results['initials']); $initialNum++) {
                     $initial = $results['initials'][$initialNum];
                     $personDescription->addStatement('given-names', $initial);
                     unset($initial);
                 }
             }
             // Surname
             if (!empty($results['surname'])) {
                 // Correct all-upper surname
                 if (strtoupper($results['surname']) == $results['surname']) {
                     $results['surname'] = ucwords(strtolower($results['surname']));
                 }
                 $personDescription->addStatement('surname', $results['surname']);
             }
             // Prefix/Suffix
             foreach (array('prefix', 'suffix') as $propertyName) {
                 if (!empty($results[$propertyName])) {
                     $results[$propertyName] = trim($results[$propertyName]);
                     $personDescription->addStatement($propertyName, $results[$propertyName]);
                 }
             }
             break;
         }
     }
     return $personDescription;
 }
 /**
  * Derive a confidence score calculated as the similarity of the
  * original raw citation and the citation text generated from the
  * citation description.
  * @param $metadataDescription MetadataDescription
  * @return integer filter confidence score
  */
 function _filterConfidenceScore(&$metadataDescription)
 {
     // Retrieve the original plain text citation.
     $originalCitation = $this->getOriginalRawCitation();
     // Generate the formatted citation output from the description.
     $citationOutputFilter =& $this->getCitationOutputFilter();
     $generatedCitation = $citationOutputFilter->execute($metadataDescription);
     // Strip formatting and the Google Scholar tag so that we get a plain
     // text string that is comparable with the raw citation.
     $generatedCitation = trim(str_replace(GOOGLE_SCHOLAR_TAG, '', strip_tags($generatedCitation)));
     // Compare the original to the generated citation.
     $citationDiff = String::diff($originalCitation, $generatedCitation);
     // Calculate similarity as the number of deleted characters in relation to the
     // number of characters in the original citation. This intentionally excludes
     // additions as these can represent useful data like a DOI or an external link.
     $deletedCharacters = 0;
     foreach ($citationDiff as $diffPart) {
         // Identify deletions.
         if (key($diffPart) == -1) {
             $deletedCharacters += String::strlen(current($diffPart));
         }
     }
     $originalCharacters = String::strlen($originalCitation);
     $partOfCommonCharacters = ($originalCharacters - $deletedCharacters) / $originalCharacters;
     $filterConfidenceScore = (int) round(min($partOfCommonCharacters * 100, 100));
     return $filterConfidenceScore;
 }
示例#24
0
 /**
  * Determine whether or not the lengths of the two supplied values are
  * "similar".
  * @param $reference string
  * @param $value string
  * @return boolean True if the lengths match very roughly.
  */
 function checkLengths($reference, $value)
 {
     $referenceLength = String::strlen($reference);
     $length = String::strlen($value);
     $lengthDifference = abs($referenceLength - $length);
     if ($referenceLength == 0) {
         return $length == 0;
     }
     if ($lengthDifference / $referenceLength > 1 && $lengthDifference > 10) {
         return false;
     }
     return true;
 }
示例#25
0
 function truncate($value, $length = 80, $ellipsis = '...')
 {
     if (String::strlen($value) > $length) {
         $value = String::substr($value, 0, $length - String::strlen($ellipsis));
         return $value . $ellipsis;
     }
     return $value;
 }
 /**
  * Helper function: Reinsert tags from the tag array into their original position in the string
  * @author Matt Crider
  * @param string
  * @param array
  * @param boolean Set to true to reinsert tags starting at the back of the string
  * @return string
  */
 function _reinsertTags($string, &$tags, $reverse = false)
 {
     if (empty($tags)) {
         return $string;
     }
     for ($i = 0; $i < count($tags); $i++) {
         $length = String::strlen($string);
         if ($tags[$i][1] < String::strlen($string)) {
             if ($reverse) {
                 if ($tags[$i][1] == 0) {
                     // Cannot use -0 as the start index (its same as +0)
                     $string = String::substr_replace($string, $tags[$i][0], $length, 0);
                 } else {
                     $string = String::substr_replace($string, $tags[$i][0], -$tags[$i][1], 0);
                 }
             } else {
                 $string = String::substr_replace($string, $tags[$i][0], $tags[$i][1], 0);
             }
         }
     }
     return $string;
 }
示例#27
0
 private function parseCondition()
 {
     $page = intval(Req::args("p"));
     $page_size = 36;
     $sort = Filter::int(Req::args("sort"));
     $sort = $sort == null ? 0 : $sort;
     $cid = Filter::int(Req::args("cid"));
     $cid = $cid == null ? 0 : $cid;
     $brand = Filter::int(Req::args("brand"));
     $price = Req::args("price");
     //下面已进行拆分过滤
     $keyword = urldecode(Req::args('keyword'));
     $keyword = Filter::text($keyword);
     $keyword = Filter::commonChar($keyword);
     //初始化数据
     $attrs = $specs = $spec_attr = $category_child = $spec_attr_selected = $selected = $has_category = $category = $current_category = array();
     $where = $spec_attr_where = $url = "";
     $condition_num = 0;
     $model = $this->model;
     //基本条件的建立
     //关于搜索的处理
     $action = strtolower(Req::args("act"));
     if ($action == 'search') {
         // xuzhongyi
         $seo_title = "分类检索";
         $seo_keywords = "全部分类";
         $seo_description = "所有分类商品";
         //取得商品的子分类
         $category_ids = "";
         $categ = Category::getInstance();
         //set:$cid = 5;
         if ($cid == 0) {
             $category_child = $categ->getCategoryChild(0, 1);
         } else {
             $current_category = $this->model->table("goods_category as gc")->fields("gc.*,gt.name as gname,gt.attr,gt.spec,gc.seo_title,gc.seo_keywords,gc.seo_description")->join("left join goods_type as gt on gc.type_id = gt.id")->where("gc.id = {$cid}")->find();
             if ($current_category) {
                 $path = trim($current_category['path'], ',');
                 $rows = $this->model->table("goods_category")->where("path like '{$current_category['path']}%'")->order("field(`id`,{$path})")->findAll();
                 $category = $this->model->table("goods_category")->where("id in ({$path})")->order("field(`id`,{$path})")->findAll();
                 foreach ($rows as $row) {
                     $category_ids .= $row['id'] . ',';
                 }
                 $category_ids = trim($category_ids, ",");
                 $category_child = $categ->getCategoryChild($path, 1);
                 $attrs = unserialize($current_category['attr']);
                 $specs = unserialize($current_category['spec']);
                 $attrs = is_array($attrs) ? $attrs : array();
                 $specs = is_array($specs) ? $specs : array();
             }
         }
         $seo_category = $model->table('goods_category')->where("id={$cid}")->find();
         if ($seo_category) {
             if ($seo_category['seo_title'] != '') {
                 $seo_title = $seo_category['seo_title'];
             } else {
                 $seo_title = $seo_category['name'];
             }
             if ($seo_category['seo_keywords'] != '') {
                 $seo_keywords = $seo_category['name'] . ',' . $seo_category['seo_keywords'];
             } else {
                 $seo_keywords = $seo_category['name'];
             }
             if ($seo_category['seo_description'] != '') {
                 $seo_description = $seo_category['seo_description'];
             } else {
                 $seo_description = $seo_category['name'];
             }
         }
         if ($category_ids != "") {
             $where = "go.category_id in ({$category_ids})";
         } else {
             $where = "1=1";
         }
         //关于类型的处理
         ////提取商品下的类型
         $seo_title = $seo_keywords = $keyword;
         $where = "name like '%{$keyword}%'";
         $rows = $model->table("goods")->fields("category_id,count(id) as num")->where($where)->group("category_id")->findAll();
         $category_ids = "";
         $category_count = array();
         foreach ($rows as $row) {
             $category_ids .= $row['category_id'] . ',';
             $category_count[$row['category_id']] = $row['num'];
         }
         $category_ids = trim($category_ids, ",");
         $has_category = array();
         $seo_description = '';
         if ($category_ids) {
             //搜索到内容且真正的点击搜索时进行统计
             if ($this->getModule()->checkToken()) {
                 $keyword = urldecode(Req::args('keyword'));
                 $keyword = Filter::sql($keyword);
                 $keyword = trim($keyword);
                 $len = String::strlen($keyword);
                 if ($len >= 2 && $len <= 8) {
                     $model = new Model("tags");
                     $obj = $model->where("name='{$keyword}'")->find();
                     if ($obj) {
                         $model->data(array('num' => "`num`+1"))->where("id=" . $obj['id'])->update();
                     } else {
                         $model->data(array('name' => $keyword))->insert();
                     }
                 }
             }
             $rows = $model->table("goods_category")->where("id in ({$category_ids})")->findAll();
             foreach ($rows as $row) {
                 $path = trim($row['path'], ',');
                 $paths = explode(',', $path);
                 $root = 0;
                 if (is_array($paths)) {
                     $root = $paths[0];
                 }
                 $row['num'] = $category_count[$row['id']];
                 $has_category[$root][] = $row;
                 $seo_description .= $row['name'] . ',';
             }
         }
         if ($cid != 0) {
             $where = "category_id={$cid} and name like '%{$keyword}%'";
             $category = $model->table("goods_category as gc ")->join("left join goods_type as gt on gc.type_id = gt.id")->where("gc.id={$cid}")->find();
             if ($category) {
                 $attrs = unserialize($category['attr']);
                 $specs = unserialize($category['spec']);
                 if ($category['seo_title'] != '') {
                     $seo_title = $category['seo_title'];
                 } else {
                     $seo_title = $category['name'];
                 }
                 if ($category['seo_keywords'] != '') {
                     $seo_keywords = $category['seo_keywords'];
                 }
                 if ($category['seo_description'] != '') {
                     $seo_description = $category['seo_description'];
                 }
             }
         }
         //关于分类检索的处理
     } else {
         if ($action == 'category') {
             $seo_title = "分类检索";
             $seo_keywords = "全部分类";
             $seo_description = "所有分类商品";
             //取得商品的子分类
             $category_ids = "";
             $categ = Category::getInstance();
             if ($cid == 0) {
                 $category_child = $categ->getCategoryChild(0, 1);
             } else {
                 $current_category = $this->model->table("goods_category as gc")->fields("gc.*,gt.name as gname,gt.attr,gt.spec,gc.seo_title,gc.seo_keywords,gc.seo_description")->join("left join goods_type as gt on gc.type_id = gt.id")->where("gc.id = {$cid}")->find();
                 if ($current_category) {
                     $path = trim($current_category['path'], ',');
                     $rows = $this->model->table("goods_category")->where("path like '{$current_category['path']}%'")->order("field(`id`,{$path})")->findAll();
                     $category = $this->model->table("goods_category")->where("id in ({$path})")->order("field(`id`,{$path})")->findAll();
                     foreach ($rows as $row) {
                         $category_ids .= $row['id'] . ',';
                     }
                     $category_ids = trim($category_ids, ",");
                     $category_child = $categ->getCategoryChild($path, 1);
                     $attrs = unserialize($current_category['attr']);
                     $specs = unserialize($current_category['spec']);
                     $attrs = is_array($attrs) ? $attrs : array();
                     $specs = is_array($specs) ? $specs : array();
                 }
             }
             $seo_category = $model->table('goods_category')->where("id={$cid}")->find();
             if ($seo_category) {
                 if ($seo_category['seo_title'] != '') {
                     $seo_title = $seo_category['seo_title'];
                 } else {
                     $seo_title = $seo_category['name'];
                 }
                 if ($seo_category['seo_keywords'] != '') {
                     $seo_keywords = $seo_category['name'] . ',' . $seo_category['seo_keywords'];
                 } else {
                     $seo_keywords = $seo_category['name'];
                 }
                 if ($seo_category['seo_description'] != '') {
                     $seo_description = $seo_category['seo_description'];
                 } else {
                     $seo_description = $seo_category['name'];
                 }
             }
             if ($category_ids != "") {
                 $where = "go.category_id in ({$category_ids})";
             } else {
                 $where = "1=1";
             }
         }
     }
     //品牌筛选
     $rows = $model->table("goods as go")->fields("brand_id,count(id) as num")->where($where)->group("brand_id")->findAll();
     $brand_ids = '';
     $brand_num = $has_brand = array();
     foreach ($rows as $row) {
         $brand_ids .= $row['brand_id'] . ',';
         $brand_num[$row['brand_id']] = $row['num'];
     }
     $brand_ids = trim($brand_ids, ',');
     //价格区间
     $prices = $model->table("goods as go")->fields("max(sell_price) as max,min(sell_price) as min,avg(sell_price) as avg")->where($where)->find();
     $price_range = Common::priceRange($prices);
     if ($brand_ids) {
         $has_brand = $model->table("brand")->where("id in ({$brand_ids})")->findAll();
     }
     //var_dump($price_range);exit();
     if (!empty($price_range)) {
         $has_price = array_flip($price_range);
     } else {
         $has_price = array();
     }
     if ($price && isset($has_price[$price])) {
         $prices = explode('-', $price);
         if (count($prices) == 2) {
             $where .= " and sell_price>=" . Filter::int($prices[0]) . " and sell_price <=" . Filter::int($prices[1]);
         } else {
             $where .= " and sell_price>=" . Filter::int($prices[0]);
         }
         $url .= "/price/{$price}";
     }
     if ($brand && isset($brand_num[$brand])) {
         $url .= "/brand/{$brand}";
         $where .= " and brand_id = {$brand} ";
     }
     //规格与属性的处理
     if ($attrs != null) {
         foreach ($attrs as $attr) {
             if ($attr['show_type'] == 1) {
                 $spec_attr[$attr['id']] = $attr;
             }
         }
     }
     if ($specs != null) {
         foreach ($specs as $spec) {
             $spec['values'] = unserialize($spec['value']);
             unset($spec['value'], $spec['spec']);
             $spec_attr[$spec['id']] = $spec;
         }
     }
     foreach ($selected as $key => $value) {
         if (isset($spec_attr[$key])) {
             $spec_attr_selected[$key] = $spec_attr[$key];
             foreach ($spec_attr_selected[$key]['values'] as $k => $v) {
                 if ($value == $v['id']) {
                     $spec_attr_selected[$key]['values'] = $v;
                     break;
                 }
             }
         }
     }
     //规格处属性的筛选
     $args = Req::args();
     unset($args['con'], $args['act'], $args['p'], $args['sort'], $args['brand'], $args['price']);
     foreach ($args as $key => $value) {
         if (is_numeric($key) && is_numeric($value)) {
             if (isset($spec_attr[$key])) {
                 $spec_attr_where .= "or (`key`={$key} and `value` = {$value}) ";
                 $condition_num++;
                 $url .= '/' . $key . '/' . $value;
             }
         }
         $selected[$key] = $value;
     }
     $selected['price'] = $price;
     $selected['brand'] = $brand;
     $spec_attr_where = trim($spec_attr_where, "or");
     $where .= ' and go.is_online =0';
     if ($condition_num > 0) {
         $where .= " and go.id in (select goods_id from tiny_spec_attr where {$spec_attr_where} group by goods_id having count(goods_id) >= {$condition_num})";
     }
     //排序的处理
     switch ($sort) {
         case '1':
             $goods_model = $model->table("goods as go")->join("left join tiny_order_goods as og on go.id = og.goods_id")->fields("go.*,sum(og.goods_nums) as sell_num")->order("sell_num desc")->group("go.id");
             break;
         case '2':
             $goods_model = $model->table("goods as go")->join("left join tiny_review as re on go.id = re.goods_id")->fields("go.*,count(re.goods_id) as renum")->group("go.id")->order("renum desc");
             break;
         case '3':
             $goods_model = $model->table("goods as go")->order("sell_price desc");
             break;
         case '4':
             $goods_model = $model->table("goods as go")->order("sell_price");
             break;
         case '5':
             $goods_model = $model->table("goods as go")->order("id desc");
             break;
         default:
             $goods_model = $model->table("goods as go")->order("sort desc");
             break;
     }
     //var_dump($where);exit;
     //提取商品
     $goods = $goods_model->where($where)->findPage($page, $page_size);
     //品牌处理
     preg_match_all('!(<(a|span)[^>]+>(上一页|下一页)</\\2>)!', $goods['html'], $matches);
     $topPageBar = "";
     if (count($matches[0]) > 0) {
         $topPageBar = implode("", $matches[0]);
     }
     $this->assign("topPageBar", $topPageBar);
     //赋值处理
     $this->assign('seo_title', $seo_title);
     $this->assign('seo_keywords', $seo_keywords);
     $this->assign('seo_description', '对应的商品共有' . $goods['page']['total'] . '件商品,包括以下分类:' . $seo_description);
     $this->assign("keyword", $keyword);
     $this->assign("sort", $sort);
     $this->assign("has_brand", $has_brand);
     $this->assign("brand_num", $brand_num);
     $this->assign("current_category", $current_category);
     $this->assign("goods", $goods);
     $this->assign("selected", $selected);
     $this->assign("spec_attr", $spec_attr);
     $this->assign("spec_attr_selected", $spec_attr_selected);
     $this->assign("category_child", $category_child);
     $this->assign("price_range", $price_range);
     $this->assign("category_nav", $category);
     $this->assign("has_category", $has_category);
     if ($action == 'search') {
         $this->assign("url", "/index/search/keyword/" . $keyword . "/cid/{$cid}/sort/{$sort}" . $url);
     } else {
         $this->assign("url", "/index/category/cid/" . $cid . "/sort/{$sort}" . $url);
     }
     $this->redirect();
 }