Building a custom facet from an ACF post type relationship

  • pseudo visitor
    Participant
    5 years, 4 months ago #8670

    Hi,

    I found in the “Knowledge Base” that custom container fields were not indexed but that their children were.

    So I was wondering about the relational fields provided by ACF. If I have a post type that has a relationship field to one or more posts of another type, a priori there is no direct way to filter for example on this relationship for a search on the first post type?

    If it is the case I would look in the hooks that you propose, I could always do it custom.

    wpsolr
    Keymaster
    5 years, 4 months ago #8671

    Hi,

    Relationship fields have been set aside for the moment, because frankly I do not know what to do in terms of search or filters.

    If you have specs, I’m interested!

    pseudo visitor
    Participant
    5 years, 4 months ago #8672

    Ok yes I understand you, the only case I had was very specific and a little far fetched: we needed to create a custom post type Author (different from the native WP Users because they did not have the possibility of connecting to the BO, it was authors in the literary sense / journalist of the term).

    In our Articles, we had a relationship to 0..n Authors. In our research, it was obviously necessary to filter on these authors, with in this case a facet with first name + name as text. I was trying to see this use case with WPSOLR, I’ll see what I can do with your doc 🙂

    nb. a priori it’s here https://www.wpsolr.com/guide/actions-and-filters/ is that it?

    wpsolr
    Keymaster
    5 years, 4 months ago #8673

    In your case, the easiest way is to “denormalize” during indexing “.

    see https://www.wpsolr.com/guide/actions-and-filters/index-modify-custom-fields/

    At the time of indexing:
    => for each post, find the authors, and fill a field meta ‘_author_nice_name’ of the post (multi-value) with the “first name + name”.
    => configure this field in screens 2.2, 2.4
    The rest is done automatically by WPSOLR.
    I’ve copied an example from the s2Member extension that deserializes a field before indexing.

    add_filter( WPSOLR_Events::WPSOLR_FILTER_POST_CUSTOM_FIELDS, [
     $this,
     'filter_custom_fields'
    ], 10, 2 );
    /**
     * Filter custom field self::CUSTOM_FIELD_NAME_STORING_POST_CAPABILITIES of a document
     *
     * s2Member serialize capabilities of the post
     * ex: a:2:{i:0;s:25:"capability1";i:1;s:25:"capability2";}
     *
     * We must unserialize it
     * ex: ['capability1', 'capability2']
     *
     * @param $custom_fields array Serialized array of capabilities
     *
     * return array Custom fields with unserialized array of capabilities in self::CUSTOM_FIELD_NAME_STORING_POST_CAPABILITIES
     */
    public function filter_custom_fields( $custom_fields, $post_id ) {
    
     // Remove the WpSolrSchema::_SOLR_DYNAMIC_TYPE_STRING at the end of the custom field
     $custom_field_name = str_replace( WpSolrSchema::_SOLR_DYNAMIC_TYPE_STRING, '', self::CUSTOM_FIELD_NAME_STORING_POST_CAPABILITIES );
    
     if ( $custom_fields && count( $custom_fields ) > 0 ) {
    
     if ( isset( $custom_fields[ $custom_field_name ] ) ) {
     $serialized_custom_field_array = $custom_fields[ $custom_field_name ];
     if ( $serialized_custom_field_array ) {
     // Field is serialiezd by s2Member; unserialize it before indexing
    
     $custom_fields[ $custom_field_name ] = unserialize( $serialized_custom_field_array[0] );
     }
          }
       }
    
     /*
          is_protected_by_s2member returns, after debugging:
       - false
       - or [s2member_level_req => i] is the level i (0, 1, 2, 3, 4) is set on the post
       - or [s2member_ccap_req => capability1] if capability1 is the first capability on the post
       Very different from what is described in the documentation !!!
       */
    
       // levels used as filters too
     $protections = is_protected_by_s2member( $post_id );
     $level       = null;
     if ( is_array( $protections ) ) {
    
     if ( isset( $protections[ self::CUSTOM_FIELD_NAME_STORING_POST_LEVEL ] ) ) {
     // level is an integer >= 0
     $level = $protections[ self::CUSTOM_FIELD_NAME_STORING_POST_LEVEL ];
    
     // Add level to custom fields, as it should have been done
     $custom_fields[ $custom_field_name ][] = $level;
     }
    
       }
    
     return $custom_fields;
    }
    pseudo visitor
    Participant
    5 years, 4 months ago #8674

    Yes great, I was looking at what you had done for directory2, it’s in the same vein.
    Thank you very much for the details!

    You have just updated the doc at the same time, no? Before I refreshed I had WpSolrFilters::WPSOLR_FILTER_POST_CUSTOM_FIELDS instead of WPSOLR_Events::WPSOLR_FILTER_POST_CUSTOM_FIELDS.

    wpsolr
    Keymaster
    5 years, 4 months ago #8675

    Yes, I have just been told that WpSolrFilters was obsolete.

    wpsolr
    Keymaster
    5 years, 4 months ago #8676

    Do not hesitate to add a topic to https://www.wpsolr.com/forums/forum/technical-configuration-issues/actions-and-filters/

    Others will appreciate some concrete examples.

    pseudo visitor
    Participant
    5 years, 4 months ago #8677

    I probably misunderstood something but I can not
    recover my custom field relationship because in tab 2.2, it is not
    not in the fields that can be checked to index.

    To lift the restriction you have to put on the fields of
    relationship type, I added the const corresponding to the types of ACF (by
    ex: “self::ACF_FIELD_TYPE_RELATIONSHIP_POST_OBJECT,”) in the table
    $indexable_acf_fields from class-wpsolr-plugin-acf.php

    Did I do well? Is there a cleaner way to do that?

    wpsolr
    Keymaster
    5 years, 4 months ago #8678

    The custom fields appear in 2.2 if they are used (enter a value in a post for example).

    Or if they are an ACF custom field, a WooCommerce attribute.

    Otherwise, to make them appear:
    WPSOLR_Events::WPSOLR_FILTER_INDEX_CUSTOM_FIELDS
    (used in WooCommerce, ACF, … to add custom fields in screen 2.2).

    pseudo visitor
    Participant
    5 years, 4 months ago #8679

    I think I still have a problem with the hook “WPSOLR_Events::WPSOLR_FILTER_POST_CUSTOM_FIELDS”.

    It fires well indexing, I tried var_dumps in all directions and the execution goes through my function. I added in $custom_fields the fields I wanted, then returned $custom_fields, and nothing is changed in the index (in doubt, I also checked in the Solr interface). Would you know if something is missing?

    wpsolr
    Keymaster
    5 years, 4 months ago #8680

    Can I see the code?

    pseudo visitor
    Participant
    5 years, 4 months ago #8681

    That’s what it gives, with “writers” being the id of ACF relation fields in an article, first name and last name id of fields in a writer. We get into the if when an article has a writer or writers linked, and the final var_dump returns what I would like to index.

    add_filter(WPSOLR_Events::WPSOLR_FILTER_POST_CUSTOM_FIELDS, 'post_custom_fields', 10, 2);

    function post_custom_fields($custom_fields, $postID) {
    
    $custom_field_name = "ecrivains";
    
    if (!isset($custom_fields)) { 
    $custom_fields = []; 
    }
    
    // var_dump($custom_fields); 
    if ( $custom_fields && count( $custom_fields ) > 0 ) {
    
    if ( isset( $custom_fields[ $custom_field_name ] ) ) { 
    $custom_fields[ $custom_field_name ] = [];
    foreach (get_field($custom_field_name, $postID) as $ecrivain){ 
    $prenom = get_field('prenom', $ecrivain); 
    $nom = get_field('nom', $ecrivain); 
    $fullname = $prenom." - ".$nom; 
    $custom_fields[$custom_field_name][] = $fullname; 
    } 
    } 
    } 
    // var_dump($custom_fields);
    
    return $custom_fields; 
    };
    wpsolr
    Keymaster
    5 years, 4 months ago #8682

    The name of the indexed field is “writers”.

    This is not a predefined field in the index schema, nor a dynamic type field. It is therefore not recognized by ES / Solr (there must be error messages in their log).

    You have to give a dynamic type to the field. Use “writers_str” should do it.

    pseudo visitor
    Participant
    5 years, 4 months ago #8683

    I replaced “$custom_fields[$custom_field_name][] = $fullname;” by “$custom_fields[$custom_field_name.” _ str “][] = $fullname;”

    Because by adding the “_str” from the entry of the function, it does not enter the 3rd if (since the field custom is called “writers”).

    You think it can come from a config problem in 2.2? Even if it would surprise me because as soon as I check the box of the field writers, the indexing crashes since (object instead of string)

    wpsolr
    Keymaster
    5 years, 4 months ago #8684

    What does not work?

Viewing 15 posts - 1 through 15 (of 21 total)

You must be logged in to reply to this topic.