WordPress.org

Make WordPress Core

Opened 3 years ago

Last modified 8 days ago

#41949 new defect (bug)

Allow multiple values for the same meta key to be passed to `wp_insert_post()`

Reported by: desrosj Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version: 4.4
Component: Posts, Post Types Keywords: has-patch
Focuses: Cc:

Description

[33910] introduced the meta_input argument to wp_insert_post(). However, there is no way to pass multiple values for the same meta key to be stored individually.

Change History (21)

#1 @stuffradio
6 weeks ago

@desrosj Were you wanting the meta_input to be able to behave the same way as tax_input?

E.g.

<?php
'tax_input' => array(
'tax_name' => array(
'term1',
'term2',
'term3'
)
);
Last edited 6 weeks ago by stuffradio (previous) (diff)

#2 @desrosj
6 weeks ago

@stuffradio Whew, this was a while ago. I believe that is what I was looking for, though.

'meta_input' => array(
    'key_1' => 1,
    'key_2' => 'some string value',
    'key_3' => '15.51,
    'visited_states' => array(
        'Massachusetts',
        'Rhode Island',
        'Washington',
        etc...
    ),
);

Currently, the only way you would be able to add meta keys with multiple values would be to use a foreach after the new post ID is returned. Ideally all meta data could just be passed in the meta_input key.

#3 @stuffradio
6 weeks ago

@desrosj

mysql> SELECT * FROM wp_postmeta WHERE post_id=12;
+---------+---------+----------------+-------------------+
| meta_id | post_id | meta_key       | meta_value        |
+---------+---------+----------------+-------------------+
|      15 |      12 | key_1          | 1                 |
|      16 |      12 | key_2          | some string value |
|      17 |      12 | key_3          | 15.51             |
|      18 |      12 | visited_states | Massachusetts     |
|      19 |      12 | visited_states | Rhode Island      |
|      20 |      12 | visited_states | Washington        |
+---------+---------+----------------+-------------------+
6 rows in set (0.00 sec)

I have created a modification locally to wp_insert_post. If I understand correctly, this was the result you were wanting to achieve with the above code?

I'll push a patch.

The meta key items above were generated from the following code

<?php
        $new_post = wp_insert_post(
                        array(
                                        'post_title' => 'Test Develop',
                                        'post_name' => 'Test Develop',
                                        'meta_input' => array(
                                                        'key_1' => 1,
                                                        'key_2' => 'some string value',
                                                        'key_3' => '15.51',
                                                        'visited_states' => array(
                                                                        'Massachusetts',
                                                                        'Rhode Island',
                                                                        'Washington',
                                                        ),
                                        )
                        )
        );

This ticket was mentioned in PR #364 on WordPress/wordpress-develop by cwuensche.


6 weeks ago

  • Keywords has-patch added; needs-patch removed

… to 'wp_insert_post()'

This PR allows for multiple values for the same meta key to be inserted using wp_insert_post().

Trac ticket: https://core.trac.wordpress.org/ticket/41949

This ticket was mentioned in Slack in #core by stuffradio. View the logs.


6 weeks ago

#6 follow-ups: @TimothyBlynJacobs
6 weeks ago

How would you differentiate between an array of meta values, or one meta value that should be an array?

#7 in reply to: ↑ 6 @stuffradio
6 weeks ago

Replying to TimothyBlynJacobs:

How would you differentiate between an array of meta values, or one meta value that should be an array?

Good point. I didn't think of the use case that you could have multiple meta keys outside an array.

#8 in reply to: ↑ 6 @stuffradio
6 weeks ago

Replying to TimothyBlynJacobs:

How would you differentiate between an array of meta values, or one meta value that should be an array?

What if I just replaced the update_post_meta with add_post_meta? Because this is wp_insert_post, why would I be updating a post meta when the meta key shouldn't exist yet?

#9 follow-up: @TimothyBlynJacobs
6 weeks ago

Sorry what I mean is that if I pass visited_states => [ 'NY', 'NJ' ]. I could want two meta rows one for 'NY' and one for 'NJ' or I would want one meta key row that saves [ 'NY', 'NJ' ].

#10 in reply to: ↑ 9 @stuffradio
6 weeks ago

Replying to TimothyBlynJacobs:

Sorry what I mean is that if I pass visited_states => [ 'NY', 'NJ' ]. I could want two meta rows one for 'NY' and one for 'NJ' or I would want one meta key row that saves [ 'NY', 'NJ' ].

I think I understand now. What if we added some flag? The default flag value could false which would keep the current behaviour and true could allow you to save the values in separate rows.

<?php
        $new_post = wp_insert_post(
                        array(
                                        'post_title' => 'Test Develop',
                                        'post_name' => 'Test Develop',
                                        'meta_input' => array(
                                                        'array_multiple_rows' => true,
                                                        'key_1' => 1,
                                                        'key_2' => 'some string value',
                                                        'key_3' => '15.51',
                                                        'visited_states' => array(
                                                                        'Massachusetts',
                                                                        'Rhode Island',
                                                                        'Washington',
                                                        ),
                                        )
                        )
        );

Not sure what a good name for the flag would be, but that would be the basic gist of it. If array_multiple_rows was true, the code above would result in multiple rows of meta rows with the same key, else it would be saved as an array.

#11 @TimothyBlynJacobs
6 weeks ago

You can take a look at register_meta it has a single flag which indicates the opposite, but could be used for this purpose. I think you'd also have to correlate it with the registered type.

There could still be backwards compatibility concerns if someone has a registeer_meta key that is single => false, with an array value, and is passing the value to meta_input. You would need to be careful that the array doesn't get broken up into multiple rows, but is still stored as a single row.

#12 @stuffradio
6 weeks ago

Here's the newest result for where I am at now.

mysql> SELECT * FROM wp_postmeta WHERE post_id=40 OR post_id=41;
+---------+---------+----------------+-------------------------------------------------------------------------------+
| meta_id | post_id | meta_key       | meta_value                                                                    |
+---------+---------+----------------+-------------------------------------------------------------------------------+
|     153 |      40 | key_1          | 1                                                                             |
|     154 |      40 | key_2          | some string value                                                             |
|     155 |      40 | key_3          | 15.51                                                                         |
|     156 |      40 | visited_states | a:3:{i:0;s:13:"Massachusetts";i:1;s:12:"Rhode Island";i:2;s:10:"Washington";} |
|     157 |      41 | key_1          | 1                                                                             |
|     158 |      41 | key_2          | some string value                                                             |
|     159 |      41 | key_3          | 15.51                                                                         |
|     160 |      41 | visited_states | Massachusetts                                                                 |
|     161 |      41 | visited_states | Rhode Island                                                                  |
|     162 |      41 | visited_states | Washington                                                                    |
+---------+---------+----------------+-------------------------------------------------------------------------------+
10 rows in set (0.00 sec)
<?php
wp_insert_post(
                        array(
                                        'post_title' => 'Single Meta Post',
                                        'post_name' => 'single-meta-post',
                                        'meta_single' => true,
                                        'meta_input' => array(
                                                        'key_1' => 1,
                                                        'key_2' => 'some string value',
                                                        'key_3' => '15.51',
                                                        'visited_states' => array(
                                                                        'Massachusetts',
                                                                        'Rhode Island',
                                                                        'Washington',
                                                        ),
                                        )
                        )
        );
<?php
wp_insert_post(
                        array(
                                        'post_title' => 'Multiple meta rows',
                                        'post_name' => 'multiple-rows',
                                        'meta_single' => false,
                                        'meta_input' => array(
                                                        'key_1' => 1,
                                                        'key_2' => 'some string value',
                                                        'key_3' => '15.51',
                                                        'visited_states' => array(
                                                                        'Massachusetts',
                                                                        'Rhode Island',
                                                                        'Washington',
                                                        ),
                                        )
                        )
        );

This ticket was mentioned in Slack in #core by stuffradio. View the logs.


6 weeks ago

This ticket was mentioned in Slack in #core by stuffradio. View the logs.


6 weeks ago

#15 @TimothyBlynJacobs
6 weeks ago

I think any kind of single flag would need to be per-meta key. You can have some meta keys that are single and some that aren't. And meta_input could contain entries from other plugins too.

#16 @stuffradio
5 weeks ago

@TimothyBlynJacobs I changed it to this now but I haven't updated the PR

<?php
wp_insert_post(
                        array(
                                        'post_title' => 'Multiple meta rows',
                                        'post_name' => 'multiple-rows',
                                        'meta_single' => false,
                                        'meta_input' => array(
                                                        'key_1' => 1,
                                                        'key_2' => 'some string value',
                                                        'key_3' => '15.51',
                                                        'visited_states' => array(
                                                                        'single' => true,
                                                                        'Massachusetts',
                                                                        'Rhode Island',
                                                                        'Washington',
                                                        ),
                                        )
                        )
        );

#17 @stuffradio
5 weeks ago

Here's a look here at the various cases I came up with. I have meta rows where the single key exists and is set to false, single key exists and is set to true and the single key doesn't exist. If the key doesn't exist, it defaults to the same as if it was set to true.

	$double_meta_post = wp_insert_post(
			array(
					'post_title' => 'Multiple meta rows',
					'post_name' => 'multiple-rows',
					'meta_single' => false,
					'meta_input' => array(
							'key_1' => 1,
							'key_2' => 'some string value',
							'key_3' => '15.51',
							'visited_states' => array(
									'single' => true,
									'Massachusetts',
									'Rhode Island',
									'Washington',
							),
					)
			)
	);

#18 @stuffradio
5 weeks ago

PR updated.

#19 @stuffradio
8 days ago

@TimothyBlynJacobs @desrosj Just hoping to get some more looks at this ticket with 5.6 development starting soon :)

#20 follow-up: @desrosj
8 days ago

Sorry @stuffradio, not ignoring you, just won't have time until 5.5 is out the door to follow up here.

#21 in reply to: ↑ 20 @stuffradio
8 days ago

Replying to desrosj:

Sorry @stuffradio, not ignoring you, just won't have time until 5.5 is out the door to follow up here.

That's understandable. I just don't want this ticket to get lost in the shuffle. :)

Note: See TracTickets for help on using tickets.