UPDATE:
I have found a workaround for the problem. It's not really a solution to the original problem per se, so I didn't want to mark it as an answer, as the solution isn't optimal in my case. I would really LOVE to understand what the problem is, as I guess it can effect both me and others in other cases.
Short recap: In a plugin I'm trying to read the content of an entries
field type, add new entries to it, and save it back (adding cinema screenings to a movie entry). For some reason it only adds one item the first time, and none after that, but leaves existing entries intact (no matter how many). I've tried checking the array both before and after modifying it in every possible way, and it looks correct. Passing an identical array, only hard coded, works perfectly every time.
I simply cannot figure out why an array that looks well-formed, and with the correct content, won't be accepted, and without throwing errors of any kind.
Temporary workaround: Building a new array with the movie ID as key, and an array of shows as value, without ever reading out the existing shows connected to a movie. When looping through this array and adding the shows to the movie, I'm able to save it, and everything works fine.
Drawback: With this "solution", I have to overwrite a movie's show listing every single time, regardless of what was there before. Most of the time this is fine, as the "master data" usually is the external data I'm loading from the ticketing system. However, I would like to add shows manually in Craft at times (for instance free shows, or shows that are not sold through the ticketing system). These will now be overwritten.
As a hack I've considered to make these extra shows as a different entry type, but that means I also need a second entry field (as the first one will always be overwritten), and then merge the contents of the two in my template to build a program. This doesn't seem like a good solution.
ORIGINAL POST:
I have a problem that's doing my head in.
I'm building a cinema program with entries for films and shows (screenings), read from external data via a custom plugin. So far, so good, I am able to create entries for both types (also with help from you guys – thanks!).
Each movie has an Entries
field type with the handle shows
that links to the shows that each represents a screening for that movie.
I'm able to retrieve the shows that are currently listed for a specific movie, and I manage with test data to save new shows to a movie, but something weird goes wrong when trying to tie it all together.
The way I do it now:
// Get the movie for the show we try to add from array of all movies
$movieEntry = $movies[$showEntry->movieID];
// Get the currently listed shows from the movie
$movieEntryShows = $movieEntry->shows->ids();
// Add show if not already there
if ( !in_array( $showEntry->id, $movieEntryShows ) ) {
array_push( $movieEntryShows, $showEntry->id );
}
// Set updated list of shows back to the movie
$movieEntry->setContentFromPost(['shows' => $movieEntryShows]);
// Save movie
$success = craft()->entries->saveEntry($movieEntry);
My problem is that when I run this the first time, every movie seem to get exactly one show added (and neither the first nor the last, although the data is loaded chronologically). Consecutive updates makes no change or addition. And no error is thrown.
I've debugged the $movieEntryShows
to check that it's actually an array, and that the values are updated and correct. They are.
I've also tried taking the data and setting it manually to a test array, and saving that instead:
$test = ['1288', '1299', '1291'];
$movieEntry->setContentFromPost(['shows' => $test]);
$success = craft()->entries->saveEntry($movieEntry);
This, for some reason, works like a charm.
I've tried every test I can think of to understand why the $test
array works, but the $movieEntryShows
does not. I have:
- Tested the types of both, and they are both
arrays
- Tested the types of all values in both arrays, and they are the same
var_dump()
-ed andprint_r()
-ed the arrays to check that they look the same (they do)- Checked that there is no index vs.
key=>value
mismatch (there isn't) array_diff()
-ed the arrays before and after adding elements, and behaves as expected
Basically, I can't for the life of me find any difference between the two arrays on any level. Still, one of them works, and the other doesn't.
I've even tried, for one specific film, to only update for one specific screening, in case there was a problem that Craft was still in the process of saving the entry from the last loop through (for other movies, it tried to add all as normal). But this doesn't seem to be the case (can't guarantee 100%, though). Also, when I've use my test array, it can add 8 shows to all movies without a hitch.
Is there anyone having any idea whatsoever why it won't accept this one specific array as a parameter, although it looks to be fine?