php-marc icon indicating copy to clipboard operation
php-marc copied to clipboard

Marc\Record->getFields() fatal error on php 8.1

Open hrvoj3e opened this issue 1 year ago • 1 comments

$xml = $this->fetchXml($identifier);
$record = Marc\Record::fromString($xml);
$fields = $record->getFields();
Fatal error: Uncaught TypeError: array_map(): Argument #2 ($array) must be of type array, 
File_MARC_List given in /einwww/mycode/marc21import/vendor/scriptotek/marc/src/Record.php:115 
Stack trace: #0 /einwww/mycode/marc21import/vendor/scriptotek/marc/src/Record.php(115): 
array_map() #1 /einwww/mycode/marc21import/Marc21Import.php(125): 
Scriptotek\Marc\Record->getFields() #2
php8.1 /usr/local/bin/composer  require scriptotek/marc


{
    "require": {
        "scriptotek/marc": "^3.0"
    }
}


  - Installing ck/php-marcspec (2.0.3): Extracting archive
  - Installing pear/pear_exception (v1.0.2): Extracting archive
  - Installing pear/file_marc (1.4.1): Extracting archive
  - Installing ck/file_marc_reference (v1.2.0): Extracting archive
  - Installing scriptotek/marc (v3.0.0): Extracting archive

I tried manually using "pear/file_marc": "master@dev" but it has not helped

{
    "require": {
        "scriptotek/marc": "^3.0",
        "pear/file_marc": "master@dev"
    }
}


  - Installing ck/php-marcspec (2.0.3): Extracting archive
  - Installing pear/pear_exception (v1.0.2): Extracting archive
  - Installing pear/file_marc (dev-master 7085b9e): Extracting archive
  - Installing ck/file_marc_reference (v1.2.0): Extracting archive
  - Installing scriptotek/marc (v3.0.0): Extracting archive

hrvoj3e avatar Mar 11 '24 11:03 hrvoj3e

There is a workaround if you force PCRE tag matching.

// fetch all fields works OK
$foundFields = $record->getFields('.*', pcre: true);


// same fix MUST be used when fetching all subfields
$fieldUsed->getSubfields('.*', pcre: true);

Scriptotek\Marc\Record::getFields() has a bug as it has in docs @return \Scriptotek\Marc\Fields\Field[] An array of wrapped fields. but that is not true and it throws fatal error.

This works because using PCRE it will return an array (it uses File_MARC_Record::getFields()) which Scriptotek\Marc\Record::getFields() expects

    function getFields($spec = null, $pcre = null)
    {
        if (!$spec) {
            return $this->fields;   // <-------- THIS IS PROBLEMATIC as it returns \File_MARC_List
        }

        // Okay, we're actually looking for something specific
        $matches = array();
        foreach ($this->fields as $field) {
            if (($pcre && preg_match("/$spec/", $field->getTag()))
                || (!$pcre && $spec == $field->getTag())
            ) {
                $matches[] = $field;
            }
        }
        return $matches;
    }

hrvoj3e avatar May 09 '24 14:05 hrvoj3e