/** * Call the callback to filter the citation. If errors occur * they'll be added to the citation form. * @param $request Request * @param $citation Citation * @param $filterCallback callable * @param $citationStateAfterFiltering integer the state the citation will * be set to after the filter was executed. * @param $fromFilterIds only use filters with the given ids * @return Citation the filtered citation or null if an error occurred */ function &_filterCitation($request, &$citation, &$filterCallback, $citationStateAfterFiltering, $fromFilterIds = array()) { // Get the context. $router = $request->getRouter(); $context = $router->getContext($request); assert(is_object($context)); // Make sure that the citation implements only one // meta-data schema. $supportedMetadataSchemas = $citation->getSupportedMetadataSchemas(); assert(count($supportedMetadataSchemas) == 1); $metadataSchema = $supportedMetadataSchemas[0]; // Extract the meta-data description from the citation. $originalDescription = $citation->extractMetadata($metadataSchema); // Let the callback configure the transformation. $transformationDefinition = call_user_func_array($filterCallback, array(&$citation, &$originalDescription, $context->getId(), $fromFilterIds)); $filterList =& $transformationDefinition['filterList']; if (empty($filterList)) { // We didn't find any applicable filter. $filteredCitation = $citationMultiplexer = $citationFilterNet = null; } else { // Get the input into the transformation. $muxInputData =& $transformationDefinition['inputData']; // Get the filter group. // NB: The filter group is identical for all filters // in the list. We can simply take the first filter's // group. $filterGroup =& $filterList[0]->getFilterGroup(); /* @var $filterGroup FilterGroup */ // The filter group must be adapted to return an array rather // than a scalar value. $filterGroup->setOutputType($filterGroup->getOutputType() . '[]'); // Instantiate the citation multiplexer filter. import('lib.pkp.classes.filter.GenericMultiplexerFilter'); $citationMultiplexer = new GenericMultiplexerFilter($filterGroup, $transformationDefinition['displayName']); // Don't fail just because one of the web services // fails. They are much too unstable to rely on them. $citationMultiplexer->setTolerateFailures(true); // Add sub-filters to the multiplexer. $nullVar = null; foreach ($filterList as $citationFilter) { if ($citationFilter->supports($muxInputData, $nullVar)) { $citationMultiplexer->addFilter($citationFilter); } } // Instantiate the citation de-multiplexer filter. // FIXME: This must be configurable if we want to support other // meta-data schemas. import('lib.pkp.plugins.metadata.nlm30.filter.Nlm30CitationDemultiplexerFilter'); $citationDemultiplexer = new Nlm30CitationDemultiplexerFilter(); $citationDemultiplexer->setOriginalDescription($originalDescription); $citationDemultiplexer->setOriginalRawCitation($citation->getRawCitation()); $citationDemultiplexer->setCitationOutputFilter($this->instantiateCitationOutputFilter($context)); // Combine multiplexer and de-multiplexer to form the // final citation filter network. import('lib.pkp.classes.filter.GenericSequencerFilter'); $citationFilterNet = new GenericSequencerFilter(PersistableFilter::tempGroup($filterGroup->getInputType(), 'class::lib.pkp.classes.citation.Citation'), 'Citation Filter Network'); $citationFilterNet->addFilter($citationMultiplexer); $citationFilterNet->addFilter($citationDemultiplexer); // Send the input through the citation filter network. $filteredCitation =& $citationFilterNet->execute($muxInputData); } if (is_null($filteredCitation)) { // Return the original citation if the filters // did not produce any results and add an error message. $filteredCitation =& $citation; if (!empty($transformationDefinition['filterList'])) { $filteredCitation->addError(__('submission.citations.filter.noResultFromFilterError')); } } else { // Copy data from the original citation to the filtered citation. $filteredCitation->setId($citation->getId()); $filteredCitation->setSequence($citation->getSequence()); $filteredCitation->setRawCitation($citation->getRawCitation()); $filteredCitation->setAssocId($citation->getAssocId()); $filteredCitation->setAssocType($citation->getAssocType()); foreach ($citation->getErrors() as $errorMessage) { $filteredCitation->addError($errorMessage); } foreach ($citation->getSourceDescriptions() as $sourceDescription) { $filteredCitation->addSourceDescription($sourceDescription); } } // Set the target citation state. $filteredCitation->setCitationState($citationStateAfterFiltering); if (is_a($citationMultiplexer, 'CompositeFilter')) { // Retrieve the results of intermediate filters and add // them to the citation for inspection by the end user. $lastOutput =& $citationMultiplexer->getLastOutput(); if (is_array($lastOutput)) { foreach ($lastOutput as $sourceDescription) { $filteredCitation->addSourceDescription($sourceDescription); } } } if (is_a($citationFilterNet, 'CompositeFilter')) { // Add filtering errors (if any) to the citation's error list. foreach ($citationFilterNet->getErrors() as $filterError) { $filteredCitation->addError($filterError); } } return $filteredCitation; }
/** * Call the callback to filter the citation. If errors occur * they'll be added to the citation form. * @param $request Request * @param $citation Citation * @param $filterCallback callable * @param $citationStateAfterFiltering integer the state the citation will * be set to after the filter was executed. * @param $fromFilterIds only use filters with the given ids * @return Citation the filtered citation or null if an error occurred */ function &_filterCitation(&$request, &$citation, &$filterCallback, $citationStateAfterFiltering, $fromFilterIds = array()) { // Get the context. $router =& $request->getRouter(); $context =& $router->getContext($request); assert(is_object($context)); // Make sure that the citation implements the // meta-data schema. (We currently only support // NLM citation.) $supportedMetadataSchemas =& $citation->getSupportedMetadataSchemas(); assert(count($supportedMetadataSchemas) == 1); $metadataSchema =& $supportedMetadataSchemas[0]; assert(is_a($metadataSchema, 'NlmCitationSchema')); // Extract the meta-data description from the citation. $originalDescription =& $citation->extractMetadata($metadataSchema); // Let the callback configure the transformation. $transformationDefinition = call_user_func_array($filterCallback, array(&$citation, &$originalDescription, $context->getId(), $fromFilterIds)); if (empty($transformationDefinition['filterList'])) { // We didn't find any applicable filter. $filteredCitation = $citationMultiplexer = $citationFilterNet = null; } else { // Get the input into the transformation. $muxInputData =& $transformationDefinition['inputData']; // Instantiate the citation multiplexer filter. import('lib.pkp.classes.filter.GenericMultiplexerFilter'); $citationMultiplexer = new GenericMultiplexerFilter($transformationDefinition['displayName'], $transformationDefinition['transformation']); // Don't fail just because one of the web services // fails. They are much too unstable to rely on them. $citationMultiplexer->setTolerateFailures(true); // Add sub-filters to the multiplexer. $nullVar = null; foreach ($transformationDefinition['filterList'] as $citationFilter) { if ($citationFilter->supports($muxInputData, $nullVar)) { $citationMultiplexer->addFilter($citationFilter); unset($citationFilter); } } // Instantiate the citation de-multiplexer filter import('lib.pkp.classes.citation.NlmCitationDemultiplexerFilter'); $citationDemultiplexer = new NlmCitationDemultiplexerFilter(); $citationDemultiplexer->setOriginalDescription($originalDescription); $citationDemultiplexer->setOriginalRawCitation($citation->getRawCitation()); $citationDemultiplexer->setCitationOutputFilter($this->instantiateCitationOutputFilter($context)); // Combine multiplexer and de-multiplexer to form the // final citation filter network. $sequencerTransformation = array($transformationDefinition['transformation'][0], 'class::lib.pkp.classes.citation.Citation'); import('lib.pkp.classes.filter.GenericSequencerFilter'); $citationFilterNet = new GenericSequencerFilter('Citation Filter Network', $sequencerTransformation); $citationFilterNet->addFilter($citationMultiplexer); $citationFilterNet->addFilter($citationDemultiplexer); // Send the input through the citation filter network. $filteredCitation =& $citationFilterNet->execute($muxInputData); } if (is_null($filteredCitation)) { // Return the original citation if the filters // did not produce any results and add an error message. $filteredCitation =& $citation; if (!empty($transformationDefinition['filterList'])) { $filteredCitation->addError(Locale::translate('submission.citations.filter.noResultFromFilterError')); } } else { // Copy data from the original citation to the filtered citation. $filteredCitation->setId($citation->getId()); $filteredCitation->setSeq($citation->getSeq()); $filteredCitation->setRawCitation($citation->getRawCitation()); $filteredCitation->setAssocId($citation->getAssocId()); $filteredCitation->setAssocType($citation->getAssocType()); foreach ($citation->getErrors() as $errorMessage) { $filteredCitation->addError($errorMessage); } foreach ($citation->getSourceDescriptions() as $sourceDescription) { $filteredCitation->addSourceDescription($sourceDescription); unset($sourceDescription); } } // Set the target citation state. $filteredCitation->setCitationState($citationStateAfterFiltering); if (is_a($citationMultiplexer, 'CompositeFilter')) { // Retrieve the results of intermediate filters and add // them to the citation for inspection by the end user. $lastOutput =& $citationMultiplexer->getLastOutput(); if (is_array($lastOutput)) { foreach ($lastOutput as $sourceDescription) { $filteredCitation->addSourceDescription($sourceDescription); unset($sourceDescription); } } } if (is_a($citationFilterNet, 'CompositeFilter')) { // Add filtering errors (if any) to the citation's error list. foreach ($citationFilterNet->getErrors() as $filterError) { $filteredCitation->addError($filterError); } } return $filteredCitation; }