Skip to content

From Magic Fields 1.x to ACF, Part 3

Other posts in this series: Part 1; Part 2; Part 3 (this post); Part 4; Part 5; Part 6; Part 7; Part 8; Part 9

I’m not sure how that happened. But somewhere along the way all of the new postmeta lines were inserted, correctly, into the database. So when I went through my carefully constructed file of queries to run I found that somehow they’d already been run. I’m sure they didn’t just run themselves, maybe there’s something in ACF that triggers these groupings?

Who knows. I’m happy it’s done and I don’t have time to go ghosthunting.

Building Out The Seasons

There has been 21 seasons since we started putting up the programs on the web site, so it wouldn’t be too much of a lift to just reconstruct them manually. But that wouldn’t make for much of a technical blog post. And since the process is very similar to what we had in Part 2, with the modifications indicated:

$query = "SELECT ID, post_title, post_content, post_type, meta_key, meta_value FROM prefix_posts
From the list of posts, get the post ID, post title, content, type etc.
LEFT JOIN prefix_term_relationships ON ID=object_id
Join the term_relationships table’s object_id to the post ID
LEFT JOIN prefix_postmeta ON ID=post_id
Join the postmeta table’s post_id to the post ID
WHERE term_taxonomy_id=30
Only select those where the term_taxonomy_id is 30, corresponding to the line in the prefix_terms table where term_id = 7 and name = Seasons.
AND (meta_key='performance_date' OR meta_key='soloists')
Of course we’re only interested here in the artists and dates

Remember that “soloists” and “performance_date” were set up in Magic Fields long ago; and “30” is simply the built-in category ID for performances.

And run the code the same way, substituting variables along the way for legibility, replacing “performers” and “works” with “soloists” and “dates”, or whatever naming convention your particular data set suggests. They could be called “A” and “B”, for all it matters. Those indices are for your benefit. Just so the meta_key and meta_value match up.

After I run it, and get it into a file, I have a bunch of entries like this:

INSERT INTO `prefix_postmeta` (post_id, meta_key, meta_value) VALUES ('112', 'performance_dates', 'a:3:{i:0;s:4:"1027";i:1;s:4:"1026";i:2;s:4:"1025";}');
INSERT INTO `prefix_postmeta` (post_id, meta_key, meta_value) VALUES ('112', 'guest_artists', 'a:6:{i:0;s:3:"107";i:1;s:2:"18";i:2;s:3:"103";i:3;s:3:"105";i:4;s:3:"109";i:5;s:2:"39";}');

That’s for post ID 112, our 2009-2010 season. You can see right out of the box, before I run the queries, that it isn’t recognizing anything.

Throwing a warning
The arrays are empty, and so is throwing warnings.

Next I’ll throw the two queries at it:


Notice: Trying to get property ‘ID’ of non-object in /path/to/ on line 17

The postmeta values are all in place, and you can see them on the edit screen:

Custom Fields in Edit Screen
These are the correct values for each field.

So what gives? I’m not sure, but the edit screens show the correct information for dates and soloists so I’m going to go ahead and run the rest of them so I have a bigger set to work with. This has something to do with “post objects.” Let’s dig in.

Post Object Arrays

I was thinking there was something esoteric about these. But it’s really just an array of integers, each representing a post ID. So I can do this for my “Seasons” page:

$performance_dates = get_field('performance_dates');
$guests = get_field('guest_artists');

And each of those is an array of post IDs. There’s a way of doing this where “$post” is somehow magic; by using the name “post” as the variable, there are super cow powers enabled. My loop ended up looking like this:

foreach ($performance_dates as $post) : ?>

Rattle through each $post (gotta be called $post) and set up the data for it.

<?php setup_postdata($post); ?>
<div class="single_section">

My HTML for the section. Display the header, wrapped in a link.

<h3><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3>

Show the contents of the ‘basic_info_date’ field, formatted in good English style. Nobody wants to see 2020-06-23 or whatever. Along with the time and location.

<?php echo date('l, F j, Y', strtotime(get_field('basic_info_date', $post))) ?>
at <?php the_field('basic_info_time'); ?>
<?php the_field('basic_info_location'); ?>

That’s just the concert information. Next, we’re going to break down the concert’s list of musical works. Start by taking the contents of the $post’s program_titles field, and putting it into an array, $repertoire.

<?php $repertoire = get_field('program_titles', $post); ?>

Then go through each repertoire item, using it’s post ID of $work:

<?php foreach ( $repertoire as $work ) : ?>
<?php echo get_field('composer', $work ) . "<br />" ?>

Show the value of the “composer” field.

<strong><a href="<?php echo get_permalink($work) ?>">
<?php echo get_field('title', $work ); ?>

Then get the permalink and the title and build a linked musical title. Sometimes — actually often — there’s a subtitle.

<?php echo get_field('subtitle', $work ); ?>
<?php endforeach ?>

And end that part of the loop. We’re still inside that original $post, the one that contains all the information about the individual program. We’ll continue on to show the soloists that will be performing.

<?php $soloistas = get_field('artist_artists', $post); ?>

$soloistas will contain all the artists that are involved in a performance. At minimum that will be the conductor, but it can also include a piano soloist, a chorus, or members of an opera cast. Here’s my HTML header and paragraph opener.


Then go through each of the $soloistas.

<?php foreach ( $soloistas as $soloista ) : ?>

Start by building a link.

<strong><a href="<?php echo get_permalink($soloista) ?>">

This is awkward. I want the soloist’s name, and if I’ve remembered to set the type of soloist — guest conductor, mezzo-soprano, pianist — I want to follow the soloist’s name with a comma (and no space!) and the type.

<?php echo get_field('name', $soloista ); ?></a></strong><?php if (get_field('type', $soloista)) : ?><?php echo ', ' . get_field('type', $soloista) ?>
<?php endif; ?>
<br />
<?php endforeach ?>


That closes the “foreach” of information about a concert. And then we’ll close out the bigger loop.

<?php wp_reset_postdata(); ?>
<?php endforeach ?>

Here’s what that all looks like on a live page:

Page Section
I also developed a section below that arranges the soloists for the season in a line, with their photos and capsule bios. Here’s the code for that.

<h3>This Season’s Guest Artists</h3>
<?php foreach ( $guests as $post ) : ?>
<div class="single_section">
<?php setup_postdata($post); ?>
<div><h4><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h4>
<?php if (get_field('photo', $post)) : ?>
<?php $image = get_field('photo', $post); ?>
<? if ( ! is_numeric($image) ) : ?>
<a href="<?php the_permalink(); ?>">
<img src="<?php echo "/wp-content/files_mf/$image" ?>" align="left" /></a>
<? elseif ($image) : ?>
<a href="<?php the_permalink(); ?>"><?php echo_get_attachment_image( $image, 'thumbnail' ); ?>
<?php endif ?>
<?php endif ?>
<?php the_excerpt(); ?>
<br clear="both" />
<?php wp_reset_postdata(); ?>
<?php endforeach; ?>

And what that section now looks like:

I’m not madly in love with this all yet. I’d like to align it better to a grid, and show the featured images for each program. But the featured images as uploaded aren’t the right size and shape; I use a plugin to develop a nice cropping, and I need to figure out how to show that on these posts.

But we’re getting closer. There’s one more step — reproducing the functionality of a sidebar widget that I’d coded a plug-in for. It was highly specific to Magic Fields, and highly resource-intensive such that I shut it down a while ago. But I’d love to bring it back.

    Leave a Reply

    Your email address will not be published. Required fields are marked *

    Share This