Example #1
0
 /**
  * File_MARC_Field constructor
  *
  * Create a new {@link File_MARC_Field} object from passed arguments. We
  * define placeholders for the arguments required by child classes.
  *
  * @param string $tag       tag
  * @param string $subfields placeholder for subfields or control data
  * @param string $ind1      placeholder for first indicator
  * @param string $ind2      placeholder for second indicator
  */
 function __construct($tag, $subfields = null, $ind1 = null, $ind2 = null)
 {
     $this->tag = $tag;
     // Check if valid tag
     if (!preg_match("/^[0-9A-Za-z]{3}\$/", $tag)) {
         $errorMessage = File_MARC_Exception::formatError(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_INVALID_TAG], array("tag" => $tag));
         throw new File_MARC_Exception($errorMessage, File_MARC_Exception::ERROR_INVALID_TAG);
     }
 }
Example #2
0
 /**
  * Decode a given raw MARC record
  *
  * Port of Andy Lesters MARC::File::USMARC->decode() Perl function into PHP.
  *
  * @param string $text Raw MARC record
  *
  * @return File_MARC_Record Decoded File_MARC_Record object
  */
 private function _decode($text)
 {
     $marc = new File_MARC_Record($this);
     $matches = array();
     if (!preg_match("/^(\\d{5})/", $text, $matches)) {
         $marc->addWarning(File_MARC_Exception::formatError(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_NONNUMERIC_LENGTH], array("record_length" => substr($text, 0, 5))));
     }
     // Store record length
     $record_length = $matches[1];
     if ($record_length != strlen($text)) {
         $marc->addWarning(File_MARC_Exception::formatError(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_INCORRECT_LENGTH], array("record_length" => $record_length, "actual" => strlen($text))));
         // give up and set the record length to the actual byte length
         $record_length = strlen($text);
     }
     if (substr($text, -1, 1) != File_MARC::END_OF_RECORD) {
         throw new File_MARC_Exception(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_INVALID_TERMINATOR], File_MARC_Exception::ERROR_INVALID_TERMINATOR);
     }
     // Store leader
     $marc->setLeader(substr($text, 0, File_MARC::LEADER_LEN));
     // bytes 12 - 16 of leader give offset to the body of the record
     $data_start = 0 + substr($text, 12, 5);
     // immediately after the leader comes the directory (no separator)
     $dir = substr($text, File_MARC::LEADER_LEN, $data_start - File_MARC::LEADER_LEN - 1);
     // -1 to allow for \x1e at end of directory
     // character after the directory must be \x1e
     if (substr($text, $data_start - 1, 1) != File_MARC::END_OF_FIELD) {
         $marc->addWarning(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_NO_DIRECTORY]);
     }
     // All directory entries 12 bytes long, so length % 12 must be 0
     if (strlen($dir) % File_MARC::DIRECTORY_ENTRY_LEN != 0) {
         $marc->addWarning(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_INVALID_DIRECTORY_LENGTH]);
     }
     // go through all the fields
     $nfields = strlen($dir) / File_MARC::DIRECTORY_ENTRY_LEN;
     for ($n = 0; $n < $nfields; $n++) {
         // As pack returns to key 1, leave place 0 in list empty
         list(, $tag) = unpack("A3", substr($dir, $n * File_MARC::DIRECTORY_ENTRY_LEN, File_MARC::DIRECTORY_ENTRY_LEN));
         list(, $len) = unpack("A3/A4", substr($dir, $n * File_MARC::DIRECTORY_ENTRY_LEN, File_MARC::DIRECTORY_ENTRY_LEN));
         list(, $offset) = unpack("A3/A4/A5", substr($dir, $n * File_MARC::DIRECTORY_ENTRY_LEN, File_MARC::DIRECTORY_ENTRY_LEN));
         // Check directory validity
         if (!preg_match("/^[0-9A-Za-z]{3}\$/", $tag)) {
             $marc->addWarning(File_MARC_Exception::formatError(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_INVALID_DIRECTORY_TAG], array("tag" => $tag)));
         }
         if (!preg_match("/^\\d{4}\$/", $len)) {
             $marc->addWarning(File_MARC_Exception::formatError(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_INVALID_DIRECTORY_TAG_LENGTH], array("tag" => $tag, "len" => $len)));
         }
         if (!preg_match("/^\\d{5}\$/", $offset)) {
             $marc->addWarning(File_MARC_Exception::formatError(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_INVALID_DIRECTORY_OFFSET], array("tag" => $tag, "offset" => $offset)));
         }
         if ($offset + $len > $record_length) {
             $marc->addWarning(File_MARC_Exception::formatError(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_INVALID_DIRECTORY], array("tag" => $tag)));
         }
         $tag_data = substr($text, $data_start + $offset, $len);
         if (substr($tag_data, -1, 1) == File_MARC::END_OF_FIELD) {
             /* get rid of the end-of-tag character */
             $tag_data = substr($tag_data, 0, -1);
             $len--;
         } else {
             $marc->addWarning(File_MARC_Exception::formatError(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_FIELD_EOF], array("tag" => $tag)));
         }
         if (preg_match("/^\\d+\$/", $tag) and $tag < 10) {
             $marc->appendField(new File_MARC_Control_Field($tag, $tag_data));
         } else {
             $subfields = explode(File_MARC::SUBFIELD_INDICATOR, $tag_data);
             $indicators = array_shift($subfields);
             if (strlen($indicators) != 2) {
                 $errorMessage = File_MARC_Exception::formatError(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_INVALID_INDICATORS], array("tag" => $tag, "indicators" => $indicators));
                 $marc->addWarning($errorMessage);
                 // Do the best with the indicators we've got
                 if (strlen($indicators) == 1) {
                     $ind1 = $indicators;
                     $ind2 = " ";
                 } else {
                     list($ind1, $ind2) = array(" ", " ");
                 }
             } else {
                 $ind1 = substr($indicators, 0, 1);
                 $ind2 = substr($indicators, 1, 1);
             }
             // Split the subfield data into subfield name and data pairs
             $subfield_data = array();
             foreach ($subfields as $subfield) {
                 if (strlen($subfield) > 0) {
                     $subfield_data[] = new File_MARC_Subfield(substr($subfield, 0, 1), substr($subfield, 1));
                 } else {
                     $errorMessage = File_MARC_Exception::formatError(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_EMPTY_SUBFIELD], array("tag" => $tag));
                     $marc->addWarning($errorMessage);
                 }
             }
             if (!isset($subfield_data)) {
                 $errorMessage = File_MARC_Exception::formatError(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_EMPTY_SUBFIELD], array("tag" => $tag));
                 $marc->addWarning($errorMessage);
             }
             // If the data is invalid, let's just ignore the one field
             try {
                 $new_field = new File_MARC_Data_Field($tag, $subfield_data, $ind1, $ind2);
                 $marc->appendField($new_field);
             } catch (Exception $e) {
                 $marc->addWarning($e->getMessage());
             }
         }
     }
     return $marc;
 }
Example #3
0
 /**
  * Inserts a field in the MARC record relative to an existing field
  *
  * Inserts a {@link File_MARC_Control_Field} or {@link File_MARC_Data_Field}
  * object before or after a specified existing field.
  *
  * <code>
  * // Example: Insert a new field before the first 650 field
  *
  * // Create the new field
  * $subfields[] = new File_MARC_Subfield('a', 'Scott, Daniel.');
  * $new_field = new File_MARC_Data_Field('100', $subfields, 0, null);
  *
  * // Retrieve the target field for our insertion point
  * $subject = $record->getFields('650');
  *
  * // Insert the new field
  * if (is_array($subject)) {
  *     $record->insertField($new_field, $subject[0], true);
  * }
  * elseif ($subject) {
  *     $record->insertField($new_field, $subject, true);
  * }
  * </code>
  *
  * @param File_MARC_Field $new_field      The field to add
  * @param File_MARC_Field $existing_field The target field
  * @param bool            $before         Insert the new field before the existing field if true, after the existing field if false
  *
  * @return File_MARC_Field                The field that was added
  */
 function insertField(File_MARC_Field $new_field, File_MARC_Field $existing_field, $before = false)
 {
     switch ($before) {
         /* Insert before the specified field in the record */
         case true:
             $this->fields->insertNode($new_field, $existing_field, true);
             break;
             /* Insert after the specified field in the record */
         /* Insert after the specified field in the record */
         case false:
             $this->fields->insertNode($new_field, $existing_field);
             break;
         default:
             $errorMessage = File_MARC_Exception::formatError(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_INSERTFIELD_MODE], array("mode" => $before));
             throw new File_MARC_Exception($errorMessage, File_MARC_Exception::ERROR_INSERTFIELD_MODE);
     }
     return $new_field;
 }
Example #4
0
 /**
  * Read in MARCXML records
  *
  * This function reads in files or strings that
  * contain one or more MARCXML records.
  *
  * <code>
  * <?php
  * // Retrieve MARC records from a file
  * $journals = new File_MARC('journals.mrc', SOURCE_FILE);
  *
  * // Retrieve MARC records from a string (e.g. Z39 query results)
  * $monographs = new File_MARC($raw_marc, SOURCE_STRING);
  *
  * // Retrieve MARCXML records from a string with a namespace URL
  * $records = new File_MARCXML($xml_data, File_MARC::SOURCE_STRING,"http://www.loc.gov/MARC21/slim");
  *
  * // Retrieve MARCXML records from a file with a namespace prefix
  * $records = new File_MARCXML($xml_data, File_MARC::SOURCE_FILE,"marc",true);
  * ?>
  * </code>
  *
  * @param string $source    Name of the file, or a raw MARC string
  * @param int    $type      Source of the input, either SOURCE_FILE or SOURCE_STRING
  * @param string $ns        URI or prefix of the namespace
  * @param bool   $is_prefix TRUE if $ns is a prefix, FALSE if it's a URI; defaults to FALSE
  */
 function __construct($source, $type = self::SOURCE_FILE, $ns = "", $is_prefix = false)
 {
     parent::__construct($source, $type);
     $this->counter = 0;
     switch ($type) {
         case self::SOURCE_FILE:
             $this->type = self::SOURCE_FILE;
             $this->source = simplexml_load_file($source, "SimpleXMLElement", 0, $ns, $is_prefix);
             break;
         case self::SOURCE_STRING:
             $this->type = self::SOURCE_STRING;
             $this->source = simplexml_load_string($source, "SimpleXMLElement", 0, $ns, $is_prefix);
             break;
         default:
             throw new File_MARC_Exception(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_INVALID_SOURCE], File_MARC_Exception::ERROR_INVALID_SOURCE);
     }
     if (!$this->source) {
         $errorMessage = File_MARC_Exception::formatError(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_INVALID_FILE], array('filename' => $source));
         throw new File_MARC_Exception($errorMessage, File_MARC_Exception::ERROR_INVALID_FILE);
     }
 }
Example #5
0
 /**
  * Set the value of an indicator
  *
  * @param int    $ind   number of the indicator (1 or 2)
  * @param string $value value of the indicator
  *
  * @return string       returns indicator value if it exists, otherwise false
  */
 function setIndicator($ind, $value)
 {
     switch ($ind) {
         case 1:
             $this->ind1 = $this->_validateIndicator($value);
             break;
         case 2:
             $this->ind2 = $this->_validateIndicator($value);
             break;
         default:
             $errorMessage = File_MARC_Exception::formatError(File_MARC_Exception::$messages[File_MARC_Exception::ERROR_INVALID_INDICATOR_REQUEST], array("indicator" => $ind));
             throw new File_MARC_Exception($errorMessage, File_MARC_Exception::ERROR_INVALID_INDICATOR_REQUEST);
             return false;
     }
     return $this->getIndicator($ind);
 }