Metdata Migrator Plugin

I’m attempting to write a simple plugin that copies metadata from item records to attached files if the file records represent PDF documents. I’ve got the plugin mostly written, but am having a baffling problem I’m hoping code-monkeys out there can help me fix.

The code is here:

the problem is specifically in models/MetadataMigrateProcess.php. This is the job that copies metadata for all PDF file records when the plugin is installed. The part that erases all existing metadata works perfectly, until the part of the code that starts with the comment

//now cycle through again, this time attaching metadata

The loop here executes once and then quits, copying metadata (correctly) for just one file record. I cannot for the life of me figure out why. According the the php error log, there are no syntax or runtime errors, so it must be some kind of logic error. I’ve logged variable contents as the code was executing and I see everything I would expect to see…the code just won’t loop over more than one file record. I’m sure it’s something simple that will probably make me feel like a moron once it’s pointed out, but I just can’t see it. Help!

I’m not immediately seeing anything that stands out as an obvious point of breakage. However, I’m not really sure what would happen if an Item happened to have more than one File. Not sure if that’s your case, but it might be a possibility to consider.

I assume that if you do a count of the files at the top of that loop, it gives something greater than 1? I’'d also be curious about whether the item/file combo that works is the first Item (lowest id) or last Item?

(BTW, if you have the $file object, you can get its Item with $file->getItem() instead of rebuilding the SQL query, but I don’t suspect that’s the culprit)

Since the loop is executing over individual file records, what should happen is that if an item has, say, six pdf files attached, each one should call the same parent item and copy down identical metadata to all six files. At least, that’s the intent.

I know the parent while loop is passing at least 50 items to the inner foreach loop-I’ve logged that. Both inner and outer loop seem to quit after only one iteration, which is maddening. Te lop structure itself is nearly identical to the previous loop that erases file metadata, and I’ve verified that that loop works.

???

When I switch the code to copying only selected elements rather than the entire DC metadata set, it works fine. What gives?

This is a fairly random guess, in large part because I don’t fully understand how release_object works. But, I’d experiment with the possibility that when those objects – especially the Item – are released from memory, that also clobbers the memory of the Elements. So, again just as an experiment, I’d try removing those release object calls at the end. It’s indeed possible that that could make you run out of memory, but if any progress happens, we’d at least know where the problem is.

That seems like it would explain the difference between yesterday’s and today’s code. Since what you have now looks up the Elements explicitly each pass, they’d be new each time. With the loop, if my guess/experiment is right, they’d all get removed from memory along with the Item after the first pass.

I actually found a much better way to do what I wanted to do-I modified our theme to pull down metadata from the parent object dynamically as it’s rendering the page, so that I don’t have to copy metadata around. I never did figure out what was causing this problem, but given that only some fields caused a problem, I’m inclined to think it’s some kind of character encoding issue.