/**
  * @see Filter::process()
  * @param $citationString string
  * @return MetadataDescription
  */
 function &process($citationString)
 {
     $nullVar = null;
     $queryParams = array('demo' => '3', 'textlines' => $citationString);
     // Parscit web form - the result is (mal-formed) HTML
     if (is_null($result = $this->callWebService(PARSCIT_WEBSERVICE, $queryParams, XSL_TRANSFORMER_DOCTYPE_STRING, 'POST'))) {
         return $nullVar;
     }
     $result = html_entity_decode($result);
     // Detect errors.
     if (!String::regexp_match('/.*<algorithm[^>]+>.*<\\/algorithm>.*/s', $result)) {
         $translationParams = array('filterName' => $this->getDisplayName());
         $this->addError(Locale::translate('submission.citations.filter.webserviceResultTransformationError', $translationParams));
         return $nullVar;
     }
     // Screen-scrape the tagged portion and turn it into XML.
     $xmlResult = String::regexp_replace('/.*<algorithm[^>]+>(.*)<\\/algorithm>.*/s', '\\1', $result);
     $xmlResult = String::regexp_replace('/&/', '&amp;', $xmlResult);
     // Transform the result into an array of meta-data.
     if (is_null($metadata = $this->transformWebServiceResults($xmlResult, dirname(__FILE__) . DIRECTORY_SEPARATOR . 'parscit.xsl'))) {
         return $nullVar;
     }
     // Extract a publisher from the place string if possible.
     $metadata =& $this->fixPublisherNameAndLocation($metadata);
     return $this->getNlm30CitationDescriptionFromMetadataArray($metadata);
 }
 /**
  * @see TypeDescription::parseTypeName()
  */
 function parseTypeName($typeName)
 {
     // Standard validators are based on string input.
     parent::parseTypeName('string');
     // Split the type name into validator name and arguments.
     $typeNameParts = explode('(', $typeName, 2);
     switch (count($typeNameParts)) {
         case 1:
             // no argument
             $this->_validatorArgs = '';
             break;
         case 2:
             // parse arguments (no UTF8-treatment necessary)
             if (substr($typeNameParts[1], -1) != ')') {
                 return false;
             }
             // FIXME: Escape for PHP code inclusion?
             $this->_validatorArgs = substr($typeNameParts[1], 0, -1);
             break;
     }
     // Validator name must start with a lower case letter
     // and may contain only alphanumeric letters.
     if (!String::regexp_match('/^[a-z][a-zA-Z0-9]+$/', $typeNameParts[0])) {
         return false;
     }
     // Translate the validator name into a validator class name.
     $this->_validatorClassName = 'Validator' . String::ucfirst($typeNameParts[0]);
     return true;
 }
 /**
  * Validate against a localized email field.
  * @return boolean
  */
 function isValid()
 {
     if ($this->isEmptyAndOptional()) {
         return true;
     }
     $value = $this->form->getData($this->field);
     $primaryLocale = Locale::getPrimaryLocale();
     return is_array($value) && !empty($value[$primaryLocale]) && String::regexp_match($this->regExp, $value[$primaryLocale]);
 }
 /**
  * Retrieve the export as an XML string.
  * @param $pluginUrl string the url to be requested for export.
  * @param $postParams array additional post parameters
  * @return string
  */
 protected function getXmlOnExport($pluginUrl, $postParams = array())
 {
     // Prepare HTTP session.
     $curlCh = curl_init();
     curl_setopt($curlCh, CURLOPT_POST, true);
     // Create a cookie file (required for log-in).
     $cookies = tempnam(sys_get_temp_dir(), 'curlcookies');
     // Log in.
     $loginUrl = $this->baseUrl . '/index.php/test/login/signIn';
     // Bug #8518 safety work-around
     if ($this->password[0] == '@') {
         die('CURL parameters may not begin with @.');
     }
     $loginParams = array('username' => 'admin', 'password' => $this->password);
     curl_setopt($curlCh, CURLOPT_URL, $loginUrl);
     curl_setopt($curlCh, CURLOPT_POSTFIELDS, $loginParams);
     curl_setopt($curlCh, CURLOPT_COOKIEJAR, $cookies);
     self::assertTrue(curl_exec($curlCh));
     // Request export document.
     $exportUrl = $this->baseUrl . '/index.php/test/manager/importexport/plugin/' . $pluginUrl;
     curl_setopt($curlCh, CURLOPT_URL, $exportUrl);
     // Bug #8518 safety work-around
     foreach ($postParams as $paramValue) {
         if ($paramValue[0] == '@') {
             die('CURL parameters may not begin with @.');
         }
     }
     curl_setopt($curlCh, CURLOPT_POSTFIELDS, $postParams);
     curl_setopt($curlCh, CURLOPT_HTTPHEADER, array('Accept: application/xml, application/x-gtar, */*'));
     curl_setopt($curlCh, CURLOPT_RETURNTRANSFER, true);
     curl_setopt($curlCh, CURLOPT_HEADER, true);
     $response = curl_exec($curlCh);
     do {
         list($header, $response) = explode("\r\n\r\n", $response, 2);
     } while (String::regexp_match('#HTTP/.*100#', $header));
     // Check whether we got a tar file.
     if (String::regexp_match('#Content-Type: application/x-gtar#', $header)) {
         // Save the data to a temporary file.
         $tempfile = tempnam(sys_get_temp_dir(), 'tst');
         file_put_contents($tempfile, $response);
         // Recursively extract tar file.
         $result = $this->extractTarFile($tempfile);
         unlink($tempfile);
     } else {
         $matches = null;
         String::regexp_match_get('#filename="([^"]+)"#', $header, $matches);
         self::assertTrue(isset($matches[1]));
         $result = array($matches[1] => $response);
     }
     // Destroy HTTP session.
     curl_close($curlCh);
     unlink($cookies);
     return $result;
 }
 function elementsAreEmails($elements)
 {
     if (!is_array($elements)) {
         return false;
     }
     $regexp = FormValidatorEmail::getRegexp();
     foreach ($elements as $element) {
         if (!String::regexp_match($regexp, $element)) {
             echo "{$element} failed {$regexp}<br/>\n";
             return false;
         }
     }
     return true;
 }
 /**
  * @see Filter::supports()
  * @param $input mixed
  * @param $output mixed
  * @return boolean
  */
 function supports(&$input, &$output)
 {
     // Check input type
     if (!is_string($input)) {
         return false;
     }
     // Check output type
     if (is_null($output)) {
         return true;
     }
     if (!is_string($output)) {
         return false;
     }
     // Check whether the output is correctly formatted
     return (bool) String::regexp_match("/\\d{4}(-\\d{2}(-\\d{2})?)?/", $output);
 }
 /**
  * Checks whether the given version file exists and whether it
  * contains valid data. Returns a Version object if everything
  * is ok, otherwise null.
  *
  * @param $versionFile string
  * @param $templateMgr TemplateManager
  * @return Version or null if invalid or missing version file
  */
 function &getValidPluginVersionInfo($versionFile, &$templateMgr)
 {
     $nullVar = null;
     if (FileManager::fileExists($versionFile)) {
         $versionInfo =& VersionCheck::parseVersionXML($versionFile);
     } else {
         $templateMgr->assign('message', 'manager.plugins.versionFileNotFound');
         return $nullVar;
     }
     $pluginVersion =& $versionInfo['version'];
     // Validate plugin name and type to avoid abuse
     $productType = explode(".", $versionInfo['type']);
     if (count($productType) != 2 || $productType[0] != 'plugins') {
         return $nullVar;
         $templateMgr->assign('message', 'manager.plugins.versionFileInvalid');
     }
     $namesToValidate = array($pluginVersion->getProduct(), $productType[1]);
     foreach ($namesToValidate as $nameToValidate) {
         if (!String::regexp_match('/[a-z][a-zA-Z0-9]+/', $nameToValidate)) {
             return $nullVar;
             $templateMgr->assign('message', 'manager.plugins.versionFileInvalid');
         }
     }
     return $pluginVersion;
 }
 /**
  * Insert an entry into metrics table.
  *
  * @param $record array
  * @param $errorMsg string
  */
 function insertRecord(&$record, &$errorMsg)
 {
     $recordToStore = array();
     // Required dimensions.
     $requiredDimensions = array('load_id', 'assoc_type', 'assoc_id', 'metric_type');
     foreach ($requiredDimensions as $requiredDimension) {
         if (!isset($record[$requiredDimension])) {
             $errorMsg = 'Cannot load record: missing dimension "' . $requiredDimension . '".';
             return false;
         }
         $recordToStore[$requiredDimension] = $record[$requiredDimension];
     }
     $recordToStore['assoc_type'] = (int) $recordToStore['assoc_type'];
     $recordToStore['assoc_id'] = (int) $recordToStore['assoc_id'];
     // Foreign key lookup for the publication object dimension.
     $isArticleFile = false;
     switch ($recordToStore['assoc_type']) {
         case ASSOC_TYPE_GALLEY:
         case ASSOC_TYPE_SUPP_FILE:
             if ($recordToStore['assoc_type'] == ASSOC_TYPE_GALLEY) {
                 $galleyDao =& DAORegistry::getDAO('ArticleGalleyDAO');
                 /* @var $galleyDao ArticleGalleyDAO */
                 $articleFile =& $galleyDao->getGalley($recordToStore['assoc_id']);
                 if (!is_a($articleFile, 'ArticleGalley')) {
                     $errorMsg = 'Cannot load record: invalid galley id.';
                     return false;
                 }
             } else {
                 $suppFileDao =& DAORegistry::getDAO('SuppFileDAO');
                 /* @var $suppFileDao SuppFileDAO */
                 $articleFile =& $suppFileDao->getSuppFile($recordToStore['assoc_id']);
                 if (!is_a($articleFile, 'SuppFile')) {
                     $errorMsg = 'Cannot load record: invalid supplementary file id.';
                     return false;
                 }
             }
             $articleId = $articleFile->getArticleId();
             $isArticleFile = true;
             // Don't break but go on to retrieve the article.
         // Don't break but go on to retrieve the article.
         case ASSOC_TYPE_ARTICLE:
             if (!$isArticleFile) {
                 $articleId = $recordToStore['assoc_id'];
             }
             $publishedArticleDao =& DAORegistry::getDAO('PublishedArticleDAO');
             /* @var $publishedArticleDao PublishedArticleDAO */
             $article =& $publishedArticleDao->getPublishedArticleByArticleId($articleId, null, true);
             if (is_a($article, 'PublishedArticle')) {
                 $issueId = $article->getIssueId();
             } else {
                 $issueId = null;
                 $articleDao =& DAORegistry::getDAO('ArticleDAO');
                 /* @var $articleDao ArticleDAO */
                 $article =& $articleDao->getArticle($articleId, null, true);
             }
             if (!is_a($article, 'Article')) {
                 $errorMsg = 'Cannot load record: invalid article id.';
                 return false;
             }
             $journalId = $article->getJournalId();
             break;
         case ASSOC_TYPE_ISSUE_GALLEY:
             $articleId = null;
             $issueGalleyDao =& DAORegistry::getDAO('IssueGalleyDAO');
             /* @var $issueGalleyDao IssueGalleyDAO */
             $issueGalley =& $issueGalleyDao->getGalley($recordToStore['assoc_id']);
             if (!is_a($issueGalley, 'IssueGalley')) {
                 $errorMsg = 'Cannot load record: invalid issue galley id.';
                 return false;
             }
             $issueId = $issueGalley->getIssueId();
             $issueDao =& DAORegistry::getDAO('IssueDAO');
             /* @var $issueDao IssueDAO */
             $issue =& $issueDao->getIssueById($issueId, null, true);
             if (!is_a($issue, 'Issue')) {
                 $errorMsg = 'Cannot load record: issue galley without issue.';
                 return false;
             }
             $journalId = $issue->getJournalId();
             break;
         case ASSOC_TYPE_ISSUE:
             $articleId = null;
             $issueId = $recordToStore['assoc_id'];
             $issueDao =& DAORegistry::getDAO('IssueDAO');
             $issue =& $issueDao->getIssueByPubId('publisher-id', $issueId, null, true);
             /* @var $issue Issue */
             if (!$issue) {
                 $issue =& $issueDao->getIssueById($issueId, null, true);
             }
             if (!is_a($issue, 'Issue')) {
                 $errorMsg = 'Cannot load record: invalid issue id.';
                 return false;
             }
             $journalId = $issue->getJournalId();
             break;
         case ASSOC_TYPE_JOURNAL:
             $articleId = $issueId = null;
             $journalDao =& DAORegistry::getDAO('JournalDAO');
             /* @var $journalDao JournalDAO */
             $journal =& $journalDao->getById($recordToStore['assoc_id']);
             if (!$journal) {
                 $errorMsg = 'Cannot load record: invalid journal id.';
                 return false;
             }
             $journalId = $recordToStore['assoc_id'];
             break;
         default:
             $errorMsg = 'Cannot load record: invalid association type.';
             return false;
     }
     $recordToStore['context_id'] = $journalId;
     $recordToStore['issue_id'] = $issueId;
     $recordToStore['submission_id'] = $articleId;
     // We require either month or day in the time dimension.
     if (isset($record['day'])) {
         if (!String::regexp_match('/[0-9]{8}/', $record['day'])) {
             $errorMsg = 'Cannot load record: invalid date.';
             return false;
         }
         $recordToStore['day'] = $record['day'];
         $recordToStore['month'] = substr($record['day'], 0, 6);
         if (isset($record['month']) && $recordToStore['month'] != $record['month']) {
             $errorMsg = 'Cannot load record: invalid month.';
             return false;
         }
     } elseif (isset($record['month'])) {
         if (!String::regexp_match('/[0-9]{6}/', $record['month'])) {
             $errorMsg = 'Cannot load record: invalid month.';
             return false;
         }
         $recordToStore['month'] = $record['month'];
     } else {
         $errorMsg = 'Cannot load record: Missing time dimension.';
         return false;
     }
     // File type is optional.
     if (isset($record['file_type']) && $record['file_type']) {
         $recordToStore['file_type'] = (int) $record['file_type'];
     }
     // Geolocation is optional.
     if (isset($record['country_id'])) {
         $recordToStore['country_id'] = (string) $record['country_id'];
     }
     if (isset($record['region'])) {
         $recordToStore['region'] = (string) $record['region'];
     }
     if (isset($record['city'])) {
         $recordToStore['city'] = (string) $record['city'];
     }
     // The metric must be set. If it is 0 we ignore the record.
     if (!isset($record['metric'])) {
         $errorMsg = 'Cannot load record: metric is missing.';
         return false;
     }
     if (!is_numeric($record['metric'])) {
         $errorMsg = 'Cannot load record: invalid metric.';
         return false;
     }
     $recordToStore['metric'] = (int) $record['metric'];
     // Save the record to the database.
     $fields = implode(', ', array_keys($recordToStore));
     $placeholders = implode(', ', array_pad(array(), count($recordToStore), '?'));
     $params = array_values($recordToStore);
     return $this->update("INSERT INTO metrics ({$fields}) VALUES ({$placeholders})", $params);
 }
 /**
  * Helper method that configures and optionally
  * installs a filter based on the given XML node
  * which represents a <filter> element.
  * @param $filterNode XMLNode
  * @param $persist boolean whether to install the filter
  * @return PersistableFilter the installed filter.
  */
 function &configureFilter($filterNode, $persist = true)
 {
     // Install filters.
     $filterDao =& DAORegistry::getDAO('FilterDAO');
     /* @var $filterDao FilterDAO */
     $filterGroupSymbolic = $filterNode->getAttribute('inGroup');
     $filterClassName = $filterNode->getAttribute('class');
     $isTemplate = $filterNode->getAttribute('isTemplate');
     // We have to include the filter class before going on
     // so that all required constants are defined before they
     // might be used in settings.
     if (String::regexp_match('/^[a-zA-Z0-9.]+$/', $filterClassName)) {
         import($filterClassName);
     }
     // Go through the filter sub-nodes. This can be nested
     // filters or filter settings.
     $subNodes = $filterNode->getChildren();
     $settings = array();
     $subFilters = array();
     foreach ($subNodes as $subNode) {
         /* @var $subNode XMLNode */
         switch ($subNode->getName()) {
             case 'setting':
                 // Get the filter setting.
                 list($name, $value) = $this->getFilterSetting($subNode);
                 $settings[$name] = $value;
                 unset($name, $value);
                 break;
             case 'filter':
                 // Recursively configure sub-filters.
                 $subFilter =& $this->configureFilter($subNode, false);
                 $subFilters[] =& $subFilter;
                 unset($subFilter);
                 break;
         }
     }
     // We ensure idempotence of plug-in installation by checking
     // for existing identical filters.
     $similarFilterFactory =& $filterDao->getObjectsByGroupAndClass($filterGroupSymbolic, $filterClassName, 0, $isTemplate);
     if ($similarFilterFactory->getCount() > 0) {
         // 1) Find similar filters.
         $similarFilters =& $similarFilterFactory->toArray();
         // 2) Go through similar filters and eliminate them
         //    if they don't have the exact same settings.
         foreach ($similarFilters as $index => $similarFilter) {
             /* @var $similarFilter PersistableFilter */
             if (!$this->compareFilters($similarFilter, $settings, $subFilters)) {
                 unset($similarFilters[$index]);
             }
         }
         // There can be a maximum of exactly one identical transformation
         // in the database otherwise we've somehow installed a duplicate filter.
         $identicalFilters = count($similarFilters);
         assert($identicalFilters <= 1);
         // 3) If the filter has been installed before then return the existing filter.
         if ($identicalFilters) {
             $existingFilter = array_pop($similarFilters);
             return $existingFilter;
         }
     }
     // Configure (and optionally install) the filter.
     $installedFilter =& $filterDao->configureObject($filterClassName, $filterGroupSymbolic, $settings, $isTemplate, 0, $subFilters, $persist);
     assert(is_a($installedFilter, 'PersistableFilter'));
     return $installedFilter;
 }
 /**
  * Converts a string with multiple persons
  * to an array of NLM name descriptions.
  *
  * @param $personsString string
  * @param $title boolean true to parse for title
  * @param $degrees boolean true to parse for degrees
  * @return array an array of NLM name descriptions or null
  *  if the string could not be converted
  */
 function &_parsePersonsString($personsString, $title, $degrees)
 {
     // Remove "et al"
     $personsString = String::regexp_replace('/et ?al$/', '', $personsString);
     // Remove punctuation
     $personsString = trim($personsString, ':;,');
     // Cut the authors string into pieces
     $personStrings = String::iterativeExplode(array(':', ';'), $personsString);
     // Only try to cut by comma if the pieces contain more
     // than one word to avoid splitting between last name and
     // first name.
     if (count($personStrings) == 1) {
         if (String::regexp_match('/^((\\w+\\s+)+\\w+\\s*,)+\\s*((\\w+\\s+)+\\w+)$/i', $personStrings[0])) {
             $personStrings = explode(',', $personStrings[0]);
         }
     }
     // Parse persons
     $persons = array();
     foreach ($personStrings as $personString) {
         $persons[] =& $this->_parsePersonString($personString, $title, $degrees);
     }
     return $persons;
 }
 /**
  * Do the actual web service request.
  * @param $action string
  * @param $arg string
  * @param $attachment array
  * @return boolean|string True for success, an error message otherwise.
  */
 function _doRequest($action, $arg, $attachment = null)
 {
     // Build the multipart SOAP message from scratch.
     $soapMessage = '<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" ' . 'xmlns:med="http://www.medra.org">' . '<SOAP-ENV:Header/>' . '<SOAP-ENV:Body>' . "<med:{$action}>{$arg}</med:{$action}>" . '</SOAP-ENV:Body>' . '</SOAP-ENV:Envelope>';
     $soapMessageId = $this->_getContentId($action);
     if ($attachment) {
         assert(count($attachment) == 1);
         $request = "--MIME_boundary\r\n" . $this->_getMimePart($soapMessageId, $soapMessage) . "--MIME_boundary\r\n" . $this->_getMimePart(key($attachment), current($attachment)) . "--MIME_boundary--\r\n";
         $contentType = 'multipart/related; type="text/xml"; boundary="MIME_boundary"';
     } else {
         $request = $soapMessage;
         $contentType = 'text/xml';
     }
     // Prepare HTTP session.
     $curlCh = curl_init();
     curl_setopt($curlCh, CURLOPT_RETURNTRANSFER, true);
     curl_setopt($curlCh, CURLOPT_POST, true);
     // Set up basic authentication.
     curl_setopt($curlCh, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
     curl_setopt($curlCh, CURLOPT_USERPWD, $this->_auth);
     // Set up SSL.
     curl_setopt($curlCh, CURLOPT_SSLVERSION, 3);
     curl_setopt($curlCh, CURLOPT_SSL_VERIFYPEER, false);
     // Make SOAP request.
     curl_setopt($curlCh, CURLOPT_URL, $this->_endpoint);
     $extraHeaders = array('SOAPAction: "' . $action . '"', 'Content-Type: ' . $contentType, 'UserAgent: OJS-mEDRA');
     curl_setopt($curlCh, CURLOPT_HTTPHEADER, $extraHeaders);
     curl_setopt($curlCh, CURLOPT_POSTFIELDS, $request);
     $result = true;
     $response = curl_exec($curlCh);
     // We do not localize our error messages as they are all
     // fatal errors anyway and must be analyzed by technical staff.
     if ($response === false) {
         $result = 'OJS-mEDRA: Expected string response.';
     }
     if ($result === true && ($status = curl_getinfo($curlCh, CURLINFO_HTTP_CODE)) != MEDRA_WS_RESPONSE_OK) {
         $result = 'OJS-mEDRA: Expected ' . MEDRA_WS_RESPONSE_OK . ' response code, got ' . $status . ' instead.';
     }
     curl_close($curlCh);
     // Check SOAP response by simple string manipulation rather
     // than instantiating a DOM.
     if (is_string($response)) {
         $matches = array();
         String::regexp_match_get('#<faultstring>([^<]*)</faultstring>#', $response, $matches);
         if (empty($matches)) {
             if ($attachment) {
                 assert(String::regexp_match('#<returnCode>success</returnCode>#', $response));
             } else {
                 $parts = explode("\r\n\r\n", $response);
                 $result = array_pop($parts);
                 $result = String::regexp_replace('/>[^>]*$/', '>', $result);
             }
         } else {
             $result = 'mEDRA: ' . $status . ' - ' . $matches[1];
         }
     } else {
         $result = 'OJS-mEDRA: Expected string response.';
     }
     return $result;
 }
 /**
  * Checks whether the given version file exists and whether it
  * contains valid data. Returns a Version object if everything
  * is ok, otherwise null. If $returnErroMsg is true, returns the
  * error message.
  *
  * @param $versionFile string
  * @param $returnErrorMesg boolean
  * @return Version or null/string if invalid or missing version file
  */
 function &getValidPluginVersionInfo($versionFile, $returnErrorMsg = false)
 {
     $nullVar = null;
     $errorMsg = null;
     $fileManager = new FileManager();
     if ($fileManager->fileExists($versionFile)) {
         $versionInfo =& VersionCheck::parseVersionXML($versionFile);
     } else {
         $errorMsg = 'manager.plugins.versionFileNotFound';
     }
     // Validate plugin name and type to avoid abuse
     if (is_null($errorMsg)) {
         $productType = explode(".", $versionInfo['type']);
         if (count($productType) != 2 || $productType[0] != 'plugins') {
             $errorMsg = 'manager.plugins.versionFileInvalid';
         }
     }
     if (is_null($errorMsg)) {
         $pluginVersion =& $versionInfo['version'];
         $namesToValidate = array($pluginVersion->getProduct(), $productType[1]);
         foreach ($namesToValidate as $nameToValidate) {
             if (!String::regexp_match('/[a-z][a-zA-Z0-9]+/', $nameToValidate)) {
                 $errorMsg = 'manager.plugins.versionFileInvalid';
                 break;
             }
         }
     }
     if ($errorMsg) {
         if ($returnErrorMsg) {
             return $errorMsg;
         } else {
             $templateMgr =& TemplateManager::getManager();
             $templateMgr->assign('message', $errorMsg);
             return $nullVar;
         }
     } else {
         return $pluginVersion;
     }
 }
 /**
  * Check if field value is valid.
  * Value is valid if it is empty and optional or matches regular expression.
  * @return boolean
  */
 function isValid()
 {
     return $this->isEmptyAndOptional() || String::regexp_match($this->regExp, $this->form->getData($this->field));
 }
Exemple #14
0
 /**
  * Check the passed user agent for a bot.
  * @param $userAgent string
  * @param $botRegexpsFile string An alternative file with regular
  * expressions to find bots inside user agent strings.
  * @return boolean
  */
 function isUserAgentBot($userAgent, $botRegexpsFile = USER_AGENTS_FILE)
 {
     static $botRegexps;
     Registry::set('currentUserAgentsFile', $botRegexpsFile);
     if (!isset($botRegexps[$botRegexpsFile])) {
         $botFileCacheId = md5($botRegexpsFile);
         $cacheManager =& CacheManager::getManager();
         $cache =& $cacheManager->getCache('core', $botFileCacheId, array('Core', '_botFileListCacheMiss'), CACHE_TYPE_FILE);
         $botRegexps[$botRegexpsFile] = $cache->getContents();
     }
     foreach ($botRegexps[$botRegexpsFile] as $regexp) {
         if (String::regexp_match($regexp, $userAgent)) {
             return true;
         }
     }
     return false;
 }
 /**
  * This method pre-validates the service endpoint parts before
  * we try to convert them to a file/method name. This also
  * converts all parts to lower case.
  * @param $rpcServiceEndpointParts array
  * @return array the validated service endpoint parts or null if validation
  *  does not succeed.
  */
 function _validateServiceEndpointParts($rpcServiceEndpointParts)
 {
     // Do we have data at all?
     if (is_null($rpcServiceEndpointParts) || empty($rpcServiceEndpointParts) || !is_array($rpcServiceEndpointParts)) {
         return null;
     }
     // We require at least three parts: component directory, handler
     // and method name.
     if (count($rpcServiceEndpointParts) < 3) {
         return null;
     }
     // Check that the array dimensions remain within sane limits.
     if (count($rpcServiceEndpointParts) > COMPONENT_ROUTER_PARTS_MAXDEPTH) {
         return null;
     }
     // Validate the individual endpoint parts.
     foreach ($rpcServiceEndpointParts as $key => $rpcServiceEndpointPart) {
         // Make sure that none of the elements exceeds the length limit.
         $partLen = strlen($rpcServiceEndpointPart);
         if ($partLen > COMPONENT_ROUTER_PARTS_MAXLENGTH || $partLen < COMPONENT_ROUTER_PARTS_MINLENGTH) {
             return null;
         }
         // Service endpoint URLs are case insensitive.
         $rpcServiceEndpointParts[$key] = strtolower_codesafe($rpcServiceEndpointPart);
         // We only allow letters, numbers and the hyphen.
         if (!String::regexp_match('/^[a-z0-9-]*$/', $rpcServiceEndpointPart)) {
             return null;
         }
     }
     return $rpcServiceEndpointParts;
 }
 /**
  * Insert an entry into metrics table.
  *
  * @param $record array
  * @param $errorMsg string
  */
 function insertRecord($record)
 {
     $recordToStore = array();
     // Required dimensions.
     $requiredDimensions = array('load_id', 'assoc_type', 'assoc_id', 'metric_type');
     foreach ($requiredDimensions as $requiredDimension) {
         if (!isset($record[$requiredDimension])) {
             throw new Exception('Cannot load record: missing dimension "' . $requiredDimension . '".');
         }
         $recordToStore[$requiredDimension] = $record[$requiredDimension];
     }
     $assocType = $recordToStore['assoc_type'] = (int) $recordToStore['assoc_type'];
     $assocId = $recordToStore['assoc_id'] = (int) $recordToStore['assoc_id'];
     list($contextId, $pkpSectionId, $assocObjType, $assocObjId, $submissionId, $representationId) = $this->foreignKeyLookup($assocType, $assocId);
     $recordToStore['context_id'] = $contextId;
     $recordToStore['pkp_section_id'] = $pkpSectionId;
     $recordToStore['assoc_object_type'] = $assocObjType;
     $recordToStore['assoc_object_id'] = $assocObjId;
     $recordToStore['submission_id'] = $submissionId;
     $recordToStore['representation_id'] = $representationId;
     // File type is optional.
     if (isset($record['file_type']) && $record['file_type']) {
         $recordToStore['file_type'] = (int) $record['file_type'];
     }
     // We require either month or day in the time dimension.
     if (isset($record['day'])) {
         if (!String::regexp_match('/[0-9]{8}/', $record['day'])) {
             throw new Exception('Cannot load record: invalid date.');
         }
         $recordToStore['day'] = $record['day'];
         $recordToStore['month'] = substr($record['day'], 0, 6);
         if (isset($record['month']) && $recordToStore['month'] != $record['month']) {
             throw new Exception('Cannot load record: invalid month.');
         }
     } elseif (isset($record['month'])) {
         if (!String::regexp_match('/[0-9]{6}/', $record['month'])) {
             throw new Exception('Cannot load record: invalid month.');
         }
         $recordToStore['month'] = $record['month'];
     } else {
         throw new Exception('Cannot load record: Missing time dimension.');
     }
     // Geolocation is optional.
     if (isset($record['country_id'])) {
         $recordToStore['country_id'] = (string) $record['country_id'];
     }
     if (isset($record['region'])) {
         $recordToStore['region'] = (string) $record['region'];
     }
     if (isset($record['city'])) {
         $recordToStore['city'] = (string) $record['city'];
     }
     // The metric must be set. If it is 0 we ignore the record.
     if (!isset($record['metric'])) {
         throw new Exception('Cannot load record: metric is missing.');
     }
     if (!is_numeric($record['metric'])) {
         throw new Exception('Cannot load record: invalid metric.');
     }
     $recordToStore['metric'] = (int) $record['metric'];
     // Save the record to the database.
     $fields = implode(', ', array_keys($recordToStore));
     $placeholders = implode(', ', array_pad(array(), count($recordToStore), '?'));
     $params = array_values($recordToStore);
     return $this->update("INSERT INTO metrics ({$fields}) VALUES ({$placeholders})", $params);
 }
Exemple #17
0
 /**
  * Check the passed user agent for a bot.
  * @param $userAgent string
  * @param $botRegexpsFile string An alternative file with regular
  * expressions to find bots inside user agent strings.
  * @return boolean
  */
 static function isUserAgentBot($userAgent, $botRegexpsFile = USER_AGENTS_FILE)
 {
     static $botRegexps;
     if (!isset($botRegexps[$botRegexpsFile])) {
         $botRegexps[$botRegexpsFile] = array_filter(file($botRegexpsFile), array('Core', '_filterBotRegexps'));
     }
     foreach ($botRegexps[$botRegexpsFile] as $regexp) {
         if (String::regexp_match($regexp, $userAgent)) {
             return true;
         }
     }
     return false;
 }
Exemple #18
0
 function encodeDisplayName($displayName)
 {
     if (String::regexp_match('!^[-A-Za-z0-9\\!#\\$%&\'\\*\\+\\/=\\?\\^_\\`\\{\\|\\}~]+$!', $displayName)) {
         return $displayName;
     }
     return '"' . str_replace(array('"', '\\'), '', $displayName) . '"';
 }
Exemple #19
0
 /**
  * Encode a display name for proper inclusion with an email address.
  * @param $displayName string
  * @param $send boolean True to encode the results for sending
  * @return string
  */
 function encodeDisplayName($displayName, $send = false)
 {
     if (String::regexp_match('!^[-A-Za-z0-9\\!#\\$%&\'\\*\\+\\/=\\?\\^_\\`\\{\\|\\}~]+$!', $displayName)) {
         return $displayName;
     }
     return '"' . ($send ? String::encode_mime_header(str_replace(array('"', '\\'), '', $displayName)) : str_replace(array('"', '\\'), '', $displayName)) . '"';
 }
 /**
  * Converts a string with multiple persons
  * to an array of NLM name descriptions.
  *
  * @param $personsString string
  * @param $title boolean true to parse for title
  * @param $degrees boolean true to parse for degrees
  * @return array an array of NLM name descriptions or null
  *  if the string could not be converted plus optionally a
  *  single 'et-al' string.
  */
 function &_parsePersonsString($personsString, $title, $degrees)
 {
     // Check for 'et al'.
     $personsStringBeforeEtal = String::strlen($personsString);
     $personsString = String::regexp_replace('/et ?al$/', '', $personsString);
     $etAl = $personsStringBeforeEtal == String::strlen($personsString) ? false : true;
     // Remove punctuation.
     $personsString = trim($personsString, ':;, ');
     // Cut the authors string into pieces.
     $personStrings = String::iterativeExplode(array(':', ';'), $personsString);
     // If we did not have success with simple patterns then try more complex
     // patterns to tokenize multiple-person strings.
     if (count($personStrings) == 1) {
         // The first pattern must match the whole string, the second is used
         // to extract names.
         $complexPersonsPatterns = array(array('/^((([^ \\t\\n\\r\\f\\v,.&]{2,}\\s*)+,\\s*([A-Z]\\.\\s*)+),\\s*)+(\\&|\\.\\s\\.\\s\\.)\\s*([^ \\t\\n\\r\\f\\v,.&]{2,}\\s*,\\s*([A-Z]\\.\\s*)+)$/i', '/(?:[^ \\t\\n\\r\\f\\v,.&]{2,}\\s*)+,\\s*(?:[A-Z]\\.\\s*)+/i'), array('/^((([^ \\t\\n\\r\\f\\v,&]+\\s+)+[^ \\t\\n\\r\\f\\v,&]+\\s*)[,&]\\s*)+(([^ \\t\\n\\r\\f\\v,&]+\\s+)+[^ \\t\\n\\r\\f\\v,&]+)/i', '/(?:(?:[^ \\t\\n\\r\\f\\v,&.]+|[^ \\t\\n\\r\\f\\v,&]{2,})\\s+)+(?:[^ \\t\\n\\r\\f\\v,&.]+|[^ \\t\\n\\r\\f\\v,&]{2,})/i'));
         $matched = false;
         foreach ($complexPersonsPatterns as $complexPersonsPattern) {
             // Break at the first pattern that matches.
             if ($matched = String::regexp_match($complexPersonsPattern[0], $personsString)) {
                 // Retrieve names.
                 $success = String::regexp_match_all($complexPersonsPattern[1], $personsString, $personStrings);
                 assert($success && count($personStrings) == 1);
                 $personStrings = $personStrings[0];
                 break;
             }
         }
         if (!$matched) {
             // If nothing matches then try to parse as a single person.
             $personStrings = array($personsString);
         }
     }
     // Parse persons.
     $persons = array();
     foreach ($personStrings as $personString) {
         $persons[] =& $this->_parsePersonString($personString, $title, $degrees);
     }
     // Add et-al string.
     if ($etAl) {
         $persons[] = PERSON_STRING_FILTER_ETAL;
     }
     return $persons;
 }
Exemple #21
0
/**
 * Instantiates an object for a given fully qualified
 * class name after executing several checks on the class.
 *
 * The checks prevent certain vulnerabilities when
 * instantiating classes generically.
 *
 * NB: We currently only support one constructor
 * argument. If we need arbitrary arguments later
 * we can do that via func_get_args() which allows us
 * to handle an arbitrary number of optional
 * constructor arguments. The $constructorArg
 * parameter needs to be last in the parameter list
 * to be forward compatible with this potential use
 * case.
 *
 * @param $fullyQualifiedClassName string
 * @param $expectedTypes string|array the class
 * 	must conform to at least one of the given types.
 * @param $expectedPackages string|array the class
 *  must be part of at least one of the given packages.
 * @param $expectedMethods string|array names of methods
 *  that must all be present for the requested class.
 * @param $constructorArg mixed constructor argument
 *
 * @return object|boolean the instantiated object or false
 *  if the class instantiation didn't result in the expected
 *  type.
 */
function &instantiate($fullyQualifiedClassName, $expectedTypes = null, $expectedPackages = null, $expectedMethods = null, $constructorArg = null)
{
    $errorFlag = false;
    // Validate the class name
    if (!String::regexp_match('/^[a-zA-Z0-9.]+$/', $fullyQualifiedClassName)) {
        return $errorFlag;
    }
    // Validate the class package
    if (!is_null($expectedPackages)) {
        if (is_scalar($expectedPackages)) {
            $expectedPackages = array($expectedPackages);
        }
        $validPackage = false;
        foreach ($expectedPackages as $expectedPackage) {
            // No need to use String class here as class names are always US-ASCII
            if (substr($fullyQualifiedClassName, 0, strlen($expectedPackage) + 1) == $expectedPackage . '.') {
                $validPackage = true;
                break;
            }
        }
        // Raise a fatal error if the class does not belong
        // to any of the expected packages. This is to prevent
        // certain types of code inclusion attacks.
        if (!$validPackage) {
            // Construct meaningful error message.
            $expectedPackageCount = count($expectedPackages);
            $separator = '';
            foreach ($expectedPackages as $expectedPackageIndex => $expectedPackage) {
                if ($expectedPackageIndex > 0) {
                    $separator = $expectedPackageIndex == $expectedPackageCount - 1 ? ' or ' : ', ';
                }
                $expectedPackageString .= $separator . '"' . $expectedPackage . '"';
            }
            fatalError('Trying to instantiate class "' . $fullyQualifiedClassName . '" which is not in any of the expected packages ' . $expectedPackageString . '.');
        }
    }
    // Import the requested class
    import($fullyQualifiedClassName);
    // Identify the class name
    $fullyQualifiedClassNameParts = explode('.', $fullyQualifiedClassName);
    $className = array_pop($fullyQualifiedClassNameParts);
    // Type check I: The requested class should be declared by now.
    if (!class_exists($className)) {
        fatalError('Cannot instantiate class. Class "' . $className . '" is not declared in "' . $fullyQualifiedClassName . '".');
    }
    // Check that the expected operation exists for the class.
    if (!is_null($expectedMethods)) {
        if (is_scalar($expectedMethods)) {
            $expectedMethods = array($expectedMethods);
        }
        // Lower case comparison for PHP4 compatibility.
        // We don't need the String class here as method names are
        // always US-ASCII.
        $declaredMethods = array_map('strtolower', get_class_methods($className));
        foreach ($expectedMethods as $expectedMethod) {
            $requiredMethod = strtolower($expectedMethod);
            if (!in_array($requiredMethod, $declaredMethods)) {
                return $errorFlag;
            }
        }
    }
    // Instantiate the requested class
    if (is_null($constructorArg)) {
        $classInstance = new $className();
    } else {
        $classInstance = new $className($constructorArg);
    }
    // Type check II: The object must conform to the given interface (if any).
    if (!is_null($expectedTypes)) {
        if (is_scalar($expectedTypes)) {
            $expectedTypes = array($expectedTypes);
        }
        $validType = false;
        foreach ($expectedTypes as $expectedType) {
            if (is_a($classInstance, $expectedType)) {
                $validType = true;
                break;
            }
        }
        if (!$validType) {
            return $errorFlag;
        }
    }
    return $classInstance;
}
Exemple #22
0
 /**
  * Determine whether a user agent is a bot or not using an external
  * list of regular expressions.
  */
 function isBot()
 {
     static $isBot;
     if (!isset($isBot)) {
         $userAgent = Request::getUserAgent();
         $isBot = false;
         $userAgentsFile = Config::getVar('general', 'registry_dir') . DIRECTORY_SEPARATOR . 'botAgents.txt';
         $regexps = array_filter(file($userAgentsFile), create_function('&$a', 'return ($a = trim($a)) && !empty($a) && $a[0] != \'#\';'));
         foreach ($regexps as $regexp) {
             if (String::regexp_match($regexp, $userAgent)) {
                 $isBot = true;
                 return $isBot;
             }
         }
     }
     return $isBot;
 }
Exemple #23
0
 /**
  * Determine whether a user agent is a bot or not using an external
  * list of regular expressions.
  */
 function isBot()
 {
     $_this =& PKPRequest::_checkThis();
     static $isBot;
     if (!isset($isBot)) {
         $userAgent = $_this->getUserAgent();
         $isBot = false;
         $regexps = array_filter(file(USER_AGENTS_FILE), create_function('&$a', 'return ($a = trim($a)) && !empty($a) && $a[0] != \'#\';'));
         foreach ($regexps as $regexp) {
             if (String::regexp_match($regexp, $userAgent)) {
                 $isBot = true;
                 return $isBot;
             }
         }
     }
     return $isBot;
 }