corcel / acf

Advanced Custom Fields (ACF) plugin for Corcel
128 stars 100 forks source link

Custom post types #5

Closed cjke closed 7 years ago

cjke commented 7 years ago

If resolving a field this way:

$myPost = Movie::find(1);
$myPost->acf->genre;  // not this version: $myPost->acf->text('genre');

results in an uncaught method on null exception because the constructed query looks like:

"select * from `wp_posts` where `post_type` = ? and `post_name` = ?"
?1: moives // custom content type
?2: field_5852b438321e0  // custom field name

Which sets $field to null, which in turns slips through an "un-defaulted" switch statement in the field factory. Basically this results in ->setConnection on a null. The query above should be more like:

"select * from `wp_posts` where `post_type` = 'acf-field' and `post_name` = "field_5852b438321e0"

Relevant snippets: https://github.com/corcel/acf/blob/develop/src/FieldFactory.php#L58 https://github.com/corcel/acf/blob/develop/src/Field/BasicField.php#L117

Like issue #4 happy to PR it - just trying to think of a simple way to stub out the mysql without needing to stand up an entire server

cjke commented 7 years ago

Just to be a pain :) - field_keys in acf (the plugin, not this module) aren't unique within the context of the app, infact they aren't even unique within the context of a post.

For example, if you have two custom field groups for one post type, lets say the group1 and group2 both linked to post type Post. group1 has one text field with key field_123 (named "field1"), you can duplicate that field into group2 with the same key field_123 (named "field1"). This is intended and accepted behaviour within acf (the plugin, not this module).

Source: https://support.advancedcustomfields.com/forums/topic/programmatic-duplication/

I've had this issue cropping up before for small plugins written to interact with acf.

My usual go to query to resolve this correctly is:

if (! function_exists('acf_field_from_name')) {

    function acf_field_from_name($field, $group)
    {
        global $wpdb;

        return $wpdb->get_var($wpdb->prepare("
            SELECT post.post_name as field_name
            FROM $wpdb->posts AS post
            LEFT JOIN $wpdb->posts AS parent
                ON post.post_parent = parent.id
            WHERE post.post_excerpt = %s
                AND post.post_type = 'acf-field'
                AND parent.post_excerpt = %s
                AND parent.post_type = 'acf-field-group'
        ", $field, $group));
    }
}

Usage would be something like:

acf_field_from_name('field1', 'group1');

jgrossi commented 7 years ago

@cjke hey I fixed that in the 0.1.4 version. If you still need that just update corcel/acf in composer file. I hope it helps you. JG

cjke commented 7 years ago

Dude you're killing it today - crushing issues.

Quick question out of curiosity - how did you approach the concept of the same field key possibly existing in two groups? Is it required to pass in the group name as well?

jgrossi commented 7 years ago

:-) I don't think so but it should be tested. I did not write any unit test for that. We're using _field_name to get the field key to query in wp_posts, so think you'll have problem just for the same post_id using the same field_name for example. JG

cjke commented 7 years ago

Cool cool! Thanks for the awesome lib. We're releasing a biggish site in the next month which is using React (frontend) <-> Laravel (backend) <-> Corcel <-> WP (content admin) and Corcel has been an awesome addition. If you want to mark any issues in Corcel/Corcel or Corcel/Acf as "ideal first issue", I would be happy to pick some up.

jgrossi commented 7 years ago

@cjke thanks! And if you have any suggestion just let me know! Cheers! JG