示例#1
0
 /**
  * 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;
 }
示例#2
0
 public function testCompositeFilterCrud()
 {
     $this->markTestSkipped();
     $filterDao = DAORegistry::getDAO('FilterDAO');
     // sub-filter 1
     $subFilter1Settings = array('seq' => 1, 'displayName' => '1st sub-filter');
     $subFilter1 = $filterDao->configureObject('lib.pkp.tests.classes.filter.PersistableTestFilter', 'test-filter-group', $subFilter1Settings, false, 9999, array(), false);
     // sub-sub-filters for sub-filter 2
     $subSubFilter1Settings = array('seq' => 1, 'displayName' => '1st sub-sub-filter');
     $subSubFilter1 = $filterDao->configureObject('lib.pkp.tests.classes.filter.PersistableTestFilter', 'test-filter-group', $subSubFilter1Settings, false, 9999, array(), false);
     $subSubFilter2Settings = array('seq' => 2, 'displayName' => '2nd sub-sub-filter');
     $subSubFilter2 = $filterDao->configureObject('lib.pkp.tests.classes.filter.PersistableTestFilter', 'test-filter-group', $subSubFilter2Settings, false, 9999, array(), false);
     $subSubFilters = array($subSubFilter1, $subSubFilter2);
     // sub-filter 2
     $subFilter2Settings = array('seq' => 2, 'displayName' => '2nd sub-filter');
     $subFilter2 = $filterDao->configureObject('lib.pkp.classes.filter.GenericMultiplexerFilter', 'test-filter-group', $subFilter2Settings, false, 9999, $subSubFilters, false);
     // Instantiate a composite test filter object
     $subFilters = array($subFilter1, $subFilter2);
     $testFilter = $filterDao->configureObject('lib.pkp.classes.filter.GenericSequencerFilter', 'test-filter-group', array('seq' => 1), false, 9999, $subFilters);
     self::assertInstanceOf('GenericSequencerFilter', $testFilter);
     $filterId = $testFilter->getId();
     self::assertTrue(is_numeric($filterId));
     self::assertTrue($filterId > 0);
     // Check that sub-filters were correctly
     // linked to the composite filter.
     $subFilters =& $testFilter->getFilters();
     self::assertEquals(2, count($subFilters));
     foreach ($subFilters as $subFilter) {
         self::assertTrue($subFilter->getId() > 0);
         self::assertEquals($filterId, $subFilter->getParentFilterId());
     }
     $subSubFilters =& $subFilters[2]->getFilters();
     self::assertEquals(2, count($subSubFilters));
     foreach ($subSubFilters as $subSubFilter) {
         self::assertTrue($subSubFilter->getId() > 0);
         self::assertEquals($subFilters[2]->getId(), $subSubFilter->getParentFilterId());
     }
     // Retrieve filter instance by id
     $filterById = $filterDao->getObjectById($filterId);
     self::assertEquals($testFilter, $filterById);
     // Update filter instance
     $testFilter = new GenericSequencerFilter($testFilter->getFilterGroup());
     $testFilter->setDisplayName('composite filter');
     $testFilter->setSeq(9999);
     $testFilter->setId($filterId);
     $testFilter->setIsTemplate(true);
     // leave out (sub-)sub-filter 2 but add a new (sub-)sub-filter 3
     // to test recursive update.
     $testFilter->addFilter($subFilter1);
     $subFilter3 = new GenericMultiplexerFilter($testFilter->getFilterGroup());
     $subFilter3->setDisplayName('3rd sub-filter');
     $subFilter3->addFilter($subSubFilter1);
     $subSubFilter3 = new PersistableTestFilter($testFilter->getFilterGroup());
     $subSubFilter3->setDisplayName('3rd sub-sub-filter');
     $subFilter3->addFilter($subSubFilter3);
     $testFilter->addFilter($subFilter3);
     $filterDao->updateObject($testFilter);
     $filterAfterUpdate = $filterDao->getObject($testFilter);
     self::assertEquals($testFilter, $filterAfterUpdate);
     // Delete filter instance
     $filterDao->deleteObject($testFilter);
     self::assertNull($filterDao->getObjectById($filterId));
 }
 /**
  * Installs filter template entries into the filters table.
  * FIXME: Move this to plug-in installation when moving filters to plug-ins, see #5157.
  */
 function installFilterTemplates()
 {
     // Filters are supported on PHP5+ only.
     if (!checkPhpVersion('5.0.0')) {
         return true;
     }
     $filterDao =& DAORegistry::getDAO('FilterDAO');
     $filtersToBeInstalled = array('lib.pkp.classes.citation.lookup.crossref.CrossrefNlmCitationSchemaFilter', 'lib.pkp.classes.citation.lookup.pubmed.PubmedNlmCitationSchemaFilter', 'lib.pkp.classes.citation.lookup.worldcat.WorldcatNlmCitationSchemaFilter', 'lib.pkp.classes.citation.parser.freecite.FreeciteRawCitationNlmCitationSchemaFilter', 'lib.pkp.classes.citation.parser.paracite.ParaciteRawCitationNlmCitationSchemaFilter', 'lib.pkp.classes.citation.parser.parscit.ParscitRawCitationNlmCitationSchemaFilter', 'lib.pkp.classes.citation.parser.regex.RegexRawCitationNlmCitationSchemaFilter', 'lib.pkp.classes.citation.output.abnt.NlmCitationSchemaAbntFilter', 'lib.pkp.classes.citation.output.apa.NlmCitationSchemaApaFilter', 'lib.pkp.classes.citation.output.mla.NlmCitationSchemaMlaFilter', 'lib.pkp.classes.citation.output.vancouver.NlmCitationSchemaVancouverFilter', 'lib.pkp.classes.importexport.nlm.PKPSubmissionNlmXmlFilter');
     import('lib.pkp.classes.citation.output.PlainTextReferencesListFilter');
     foreach ($filtersToBeInstalled as $filterToBeInstalled) {
         // Instantiate filter.
         $filter =& instantiate($filterToBeInstalled, 'Filter');
         // Install citation output filters as non-configurable site-wide filter instances.
         if (is_a($filter, 'NlmCitationSchemaCitationOutputFormatFilter') || is_a($filter, 'PKPSubmissionNlmXmlFilter')) {
             $filter->setIsTemplate(false);
             // Check whether the filter instance has been
             // installed before.
             $existingFilters =& $filterDao->getObjectsByClass($filterToBeInstalled, 0, false);
             // Install other filter as configurable templates.
         } else {
             $filter->setIsTemplate(true);
             // Check whether the filter template has been
             // installed before.
             $existingFilters =& $filterDao->getObjectsByClass($filterToBeInstalled, 0, true);
         }
         // Guarantee idempotence.
         if ($existingFilters->getCount()) {
             continue;
         }
         // Install the filter or template.
         $filterDao->insertObject($filter, 0);
         // If this is a citation output filter then also install a corresponding references list filter.
         if (is_a($filter, 'NlmCitationSchemaCitationOutputFormatFilter')) {
             // Only Vancouver Style listings require numerical ordering.
             if (is_a($filter, 'NlmCitationSchemaVancouverFilter')) {
                 $ordering = REFERENCES_LIST_ORDERING_NUMERICAL;
             } else {
                 $ordering = REFERENCES_LIST_ORDERING_ALPHABETICAL;
             }
             // Instantiate the filter.
             $referencesListFilter = new PlainTextReferencesListFilter($filter->getDisplayName(), $filter->getClassName(), $ordering);
             $referencesListFilter->setIsTemplate(false);
             // Install the filter.
             $filterDao->insertObject($referencesListFilter, 0);
             unset($referencesListFilter);
         }
         unset($filter);
     }
     // Composite filters are more complex to install because they
     // need to be constructed first:
     // 1) Check and install the ISBNdb filter template.
     $alreadyInstalled = false;
     $existingTemplatesFactory =& $filterDao->getObjectsByClass('lib.pkp.classes.filter.GenericSequencerFilter', 0, true);
     $existingTemplates =& $existingTemplatesFactory->toArray();
     foreach ($existingTemplates as $existingTemplate) {
         $subFilters =& $existingTemplate->getFilters();
         if (count($subFilters) != 2) {
             continue;
         }
         if (!(isset($subFilters[1]) && is_a($subFilters[1], 'IsbndbNlmCitationSchemaIsbnFilter'))) {
             continue;
         }
         if (!(isset($subFilters[2]) && is_a($subFilters[2], 'IsbndbIsbnNlmCitationSchemaFilter'))) {
             continue;
         }
         $alreadyInstalled = true;
         break;
     }
     if (!$alreadyInstalled) {
         // Instantiate the filter as a configurable template.
         $isbndbTransformation = array('metadata::lib.pkp.classes.metadata.nlm.NlmCitationSchema(CITATION)', 'metadata::lib.pkp.classes.metadata.nlm.NlmCitationSchema(CITATION)');
         import('lib.pkp.classes.filter.GenericSequencerFilter');
         $isbndbFilter = new GenericSequencerFilter('ISBNdb', $isbndbTransformation);
         $isbndbFilter->setIsTemplate(true);
         // Instantiate and add the NLM-to-ISBN filter.
         import('lib.pkp.classes.citation.lookup.isbndb.IsbndbNlmCitationSchemaIsbnFilter');
         $nlmToIsbnFilter = new IsbndbNlmCitationSchemaIsbnFilter();
         $isbndbFilter->addFilter($nlmToIsbnFilter);
         // Instantiate and add the ISBN-to-NLM filter.
         import('lib.pkp.classes.citation.lookup.isbndb.IsbndbIsbnNlmCitationSchemaFilter');
         $isbnToNlmFilter = new IsbndbIsbnNlmCitationSchemaFilter();
         $isbndbFilter->addFilter($isbnToNlmFilter);
         // Add the settings mapping.
         $isbndbFilter->setSettingsMapping(array('apiKey' => array('seq' . $nlmToIsbnFilter->getSeq() . '_apiKey', 'seq' . $isbnToNlmFilter->getSeq() . '_apiKey'), 'isOptional' => array('seq' . $nlmToIsbnFilter->getSeq() . '_isOptional', 'seq' . $isbnToNlmFilter->getSeq() . '_isOptional')));
         // Persist the composite filter.
         $filterDao->insertObject($isbndbFilter, 0);
     }
     // 3) Check and install the NLM XML 2.3 output filter.
     $alreadyInstalled = false;
     $existingTemplatesFactory =& $filterDao->getObjectsByClass('lib.pkp.classes.filter.GenericSequencerFilter', 0, false);
     $existingTemplates =& $existingTemplatesFactory->toArray();
     foreach ($existingTemplates as $existingTemplate) {
         $subFilters =& $existingTemplate->getFilters();
         if (count($subFilters) != 2) {
             continue;
         }
         if (!(isset($subFilters[1]) && is_a($subFilters[1], 'PKPSubmissionNlmXmlFilter'))) {
             continue;
         }
         if (!(isset($subFilters[2]) && is_a($subFilters[2], 'XSLTransformationFilter'))) {
             continue;
         }
         $alreadyInstalled = true;
         break;
     }
     if (!$alreadyInstalled) {
         // Instantiate the filter as a non-configurable filter instance.
         $nlm23Transformation = array('class::lib.pkp.classes.submission.Submission', 'xml::*');
         $nlm23Filter = new GenericSequencerFilter('NLM Journal Publishing V2.3 ref-list', $nlm23Transformation);
         $nlm23Filter->setIsTemplate(false);
         // Instantiate and add the NLM 3.0 export filter.
         import('lib.pkp.classes.importexport.nlm.PKPSubmissionNlmXmlFilter');
         $nlm30Filter = new PKPSubmissionNlmXmlFilter();
         $nlm23Filter->addFilter($nlm30Filter);
         // Instantiate, configure and add the NLM 3.0 to 2.3 downgrade XSL transformation.
         import('lib.pkp.classes.xslt.XSLTransformationFilter');
         $downgradeFilter = new XSLTransformationFilter('NLM 3.0 to 2.3 ref-list downgrade', array('xml::*', 'xml::*'));
         $downgradeFilter->setXSLFilename('lib/pkp/classes/importexport/nlm/nlm-ref-list-30-to-23.xsl');
         $nlm23Filter->addFilter($downgradeFilter);
         // Persist the composite filter.
         $filterDao->insertObject($nlm23Filter, 0);
     }
     return true;
 }
示例#4
0
 /**
  * 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;
 }
 /**
  * Call the callback to filter the citation. If errors occur
  * they'll be added to the citation form.
  * @param $citation Citation
  * @param $filterCallback callable
  * @param $citationStateAfterFiltering integer the state the citation will
  *  be set to after the filter was executed.
  * @param $citationForm CitationForm
  * @return Citation the filtered citation or null if an error occurred
  */
 function &_filterCitation(&$citation, &$filterCallback, $citationStateAfterFiltering, &$citationForm)
 {
     // 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
     $metadataDescription =& $citation->extractMetadata($metadataSchema);
     // Let the callback build the filter network
     $filterList = call_user_func_array($filterCallback, array(&$citation, &$metadataDescription));
     // The last entry in the filter list is the
     // input data for the returned filters.
     $muxInputData =& array_pop($filterList);
     // Initialize the sample demux input data array.
     $sampleDemuxInputData = array();
     // Instantiate the citation multiplexer filter
     import('filter.GenericMultiplexerFilter');
     $citationMultiplexer = new GenericMultiplexerFilter();
     $nullVar = null;
     foreach ($filterList as $citationFilter) {
         if ($citationFilter->supports($muxInputData, $nullVar)) {
             $citationMultiplexer->addFilter($citationFilter);
             unset($citationFilter);
             // We expect one citation description per filter
             // in the multiplexer result.
             $sampleDemuxInputData[] =& $metadataDescription;
         }
     }
     // Instantiate the citation de-multiplexer filter
     import('citation.NlmCitationDemultiplexerFilter');
     $citationDemultiplexer = new NlmCitationDemultiplexerFilter();
     $citationDemultiplexer->setOriginalCitation($citation);
     // Combine multiplexer and de-multiplexer to form the
     // final citation filter network.
     import('filter.GenericSequencerFilter');
     $citationFilterNet = new GenericSequencerFilter();
     $citationFilterNet->addFilter($citationMultiplexer, $muxInputData);
     $citationFilterNet->addFilter($citationDemultiplexer, $sampleDemuxInputData);
     // Send the input through the citation filter network.
     $filterErrors = array();
     $filteredCitation =& $citationFilterNet->execute($muxInputData);
     if (!is_null($filteredCitation)) {
         // Copy unfiltered data from the original citation to the filtered citation
         $article =& $this->getArticle();
         $filteredCitation->setId($citation->getId());
         $filteredCitation->setAssocId($article->getId());
         $filteredCitation->setAssocType(ASSOC_TYPE_ARTICLE);
         $filteredCitation->setRawCitation($citation->getRawCitation());
         $filteredCitation->setEditedCitation($citation->getEditedCitation());
         // Set the citation state
         $filteredCitation->setCitationState($citationStateAfterFiltering);
     }
     return $filteredCitation;
 }
 /**
  * Identify the requested citation, call the given callback to filter
  * it, persist it and re-display it in the citation form.
  * @param $request PKPRequest
  * @param $args array
  * @param $filterCallback callable
  * @param $citationStateAfterFiltering integer the state the citation will
  *  be set to after the filter was executed.
  * @return string
  */
 function &_filterCitation(&$request, $args, &$filterCallback, $citationStateAfterFiltering)
 {
     // Identify the citation to be filtered
     $citation =& $this->_getCitationFromArgs($args);
     // 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
     $metadataDescription =& $citation->extractMetadata($metadataSchema);
     // Let the callback build the filter network
     $filterList = call_user_func($filterCallback, $citation, $metadataDescription);
     // The last entry in the filter list is the
     // input data for the returned filters.
     $muxInputData =& array_pop($filterList);
     // Initialize the sample demux input data array.
     $sampleDemuxInputData = array();
     // Instantiate the citation multiplexer filter
     import('filter.GenericMultiplexerFilter');
     $citationMultiplexer = new GenericMultiplexerFilter();
     $nullVar = null;
     foreach ($filterList as $citationFilter) {
         if ($citationFilter->supports($muxInputData, $nullVar)) {
             $citationMultiplexer->addFilter($citationFilter);
             unset($citationFilter);
             // We expect one citation description per filter
             // in the multiplexer result.
             $sampleDemuxInputData[] =& $metadataDescription;
         }
     }
     // Instantiate the citation de-multiplexer filter
     import('citation.NlmCitationDemultiplexerFilter');
     $citationDemultiplexer = new NlmCitationDemultiplexerFilter();
     $citationDemultiplexer->setOriginalCitation($citation);
     // Combine multiplexer and de-multiplexer to form the
     // final citation filter network.
     import('filter.GenericSequencerFilter');
     $citationFilterNet = new GenericSequencerFilter();
     $citationFilterNet->addFilter($citationMultiplexer, $muxInputData);
     $citationFilterNet->addFilter($citationDemultiplexer, $sampleDemuxInputData);
     // Send the input through the citation filter network.
     $filterErrors = array();
     $filteredCitation =& $citationFilterNet->execute($muxInputData);
     if (is_null($filteredCitation)) {
         // Re-display the current citation unchanged with an error message
         $filterErrors = array('editedCitation' => Locale::translate('submission.citations.form.filterError'));
         $filteredCitation =& $citation;
     } else {
         // Copy unfiltered data from the original citation to the filtered citation
         $article =& $this->getArticle();
         $filteredCitation->setId($citation->getId());
         $filteredCitation->setAssocId($article->getId());
         $filteredCitation->setAssocType(ASSOC_TYPE_ARTICLE);
         $filteredCitation->setRawCitation($citation->getRawCitation());
         $filteredCitation->setEditedCitation($citation->getEditedCitation());
         // Set the citation state
         $filteredCitation->setCitationState($citationStateAfterFiltering);
         // Persist the filtered citation
         $citationDAO =& DAORegistry::getDAO('CitationDAO');
         $citationDAO->updateCitation($filteredCitation);
     }
     // Re-display the form
     import('controllers.grid.citation.form.CitationForm');
     $citationForm = new CitationForm($filteredCitation);
     foreach ($filterErrors as $field => $message) {
         $citationForm->addError($field, $message);
     }
     $citationForm->initData();
     $citationForm->display($request);
     // The form has already been displayed.
     $emptyString = '';
     return $emptyString;
 }