Advanced Custom Fields (ACF, WordPress plugin)

Uit De Vliegende Brigade
Naar navigatie springen Naar zoeken springen

Advanced Custom Fields (ACF), developed and sold by WP Engine, seems to be the default WordPress plugin for defining custom fields and field sets.

ACF & ACF Pro

When ACF Pro has been installed, the free ACF plugin is not needed anymore, and can be deleted.

Feature comparison ACF (free) - ACF Pro (paid)
Feature ACF (Free) ACF Pro (Paid)
Basic custom fields (text, image, etc.) Yes Yes
Repeater Field No Yes
Flexible Content Field No Yes
Gallery Field No Yes
Clone Field No Yes
Options Pages No Yes
More advanced customization & control Limited Expanded

Licenses ACF Pro

  • GPLv2+
  • Paid updates.

Details

  • Licenses for ACF Pro are handled through regular license keys
  • ACF is reselled by WP Engine
  • Licences are handled through accounts at ACF's own site: advancedcustomfields.com/my-account/view-licenses
  • It seems that without valid license key (e.g., when removing the license key from a site), that pro features are disabled - Which I believe, violates the GPL.

Retrieve key from site? - Probably not

At one moment, I couldn't find my license key. SQL code that I used to maybe retrieve it:

select
   *
from
   wp_options
where
   (
      option_name like "%adv%"
      or
      option_name like "%acf%"
   )
   and not
   (
      option_name like "%search%"
      or
      option_name like "%discount%"
   )

The wp_options field with option_name acf_pro_license seems most promising to contain the license key. To retrieve this using WP-CLI:

wp option get acf_pro_license

However, although it may indeed contain the license key, it doesn't do so in a human-readible format.

Introduction to custom fields

  • For an introduction, see this introduction
  • Example: You want a hero shot on your home page. With custom fields you can configure that. That is also possible with standard WordPress, but with ACF it is easier [1].

Field groups

  • Within ACF, fields are organized into field groups. You can then associate field groups with objects (pages, posts, etc.). You can easily find out what the field group of a page is, by clicking (in the backend, of course) on the gear next to the title of a field group.
  • Field groups seem to come in different shapes and sizes, including page, clone, detail, etc.

Database model

  • Definitions of ACF fields are stored in table wp_posts
  • Instances of ACF fields that are associated with posts (e.g. the aforementioned hero shot), are stored in table wp_postmeta
  • Instances of ACF fields that are not associated with specific posts, are stored in table wp_options

Fetch field definitions

#
# * Read the definition of field hero_shop
# * Output below is manually adjusted: Normally it doesn't come out so nicely wrapped
#
select
    post_content,
    post_title,
    post_excerpt,
    post_name
from
    wp_posts
where
    post_type like "acf-field"
    and
    post_title like "Hero text";

+------------------------------------------------------------------------------------+------------+--------------+---------------------+
| post_content                                                                       | post_title | post_excerpt |      post_name      |
+------------------------------------------------------------------------------------+------------+--------------+---------------------+
| a:10:{s:4:"type";s:7:"wysiwyg";s:12:"instructions";s:0:"";s:8:"required";i:0;s:17: |            |              |                     |
| "conditional_logic";i:0;s:7:"wrapper";a:3:{s:5:"width";s:0:"";s:5:"class";s:0:"";s:| Hero text  | hero_text    | field_5d4d3c8f72ecd | 
| 2:"id";s:0:"";}s:13:"default_value";s:0:"";s:4:"tabs";s:3:"all";s:7:"toolbar";s:4: |            |              |                     |
| "full";s:12:"media_upload";i:1;s:5:"delay";i:0;}                                   |            |              |                     |
+------------------------------------------------------------------------------------+------------+--------------+---------------------+

Fetch values

To read the value of a field stored in wp_postmeta using WP-CLI:

$ wp post meta list 7 --keys=hero_text

+---------+-----------+-----------------+
| post_id | meta_key  | meta_value      |
+---------+-----------+-----------------+
| 7       | hero_text | Eat more chips! |
+---------+-----------+-----------------+

In SQL:

select 
    * 
from
    wp_postmeta 
where 
    meta_key like "hero_text";

+---------+---------+-----------+-----------------+
| meta_id | post_id | meta_key  | meta_value      |
+---------+---------+-----------+-----------------+
|    3825 |       7 | hero_text | Eat more chips! |
+---------+---------+-----------+-----------------+

WP-CLI & ACF automation

ACF doesn't seem to have its own WP-CLI commands and there don't seem to be any commands to automate ACF fields (add, remove, update).

The only thing I found is an open-source snippet from Hoppinger: https://github.com/hoppinger/advanced-custom-fields-wpcli. This seems to allow you to import and export ACF field groups. It doesn't have any other features.

PHP API & ACF automation

ACF comes with a set of PHP commands to automate things. See ACF & PHP API (WordPress for details.

PHP API & Automation: have_rows loops

(this paragraph refers to a completed project from 2020)

If an ACF object contains repeaters (fields that can contain multiple records) or flexible content (e.g. you don't know in advance what you will find), you can iterate over the content of such an object using have_rows() + the_row(). Here the_row() is a WordPress Core function to select and update a next row. So it keeps a counter for have_rows().

Use e.g. get_fields or get_field_objects to retrieve all ACF objects of a post. Then you know what the top-level entity is

Case: Automatic plugin activation (2021)

I regularly clone sites in a headless way, so in code. Can I also activate ACF Pro via code? Just cloning doesn't seem to work

  • [2]: ACF Pro key needs to be reapplied any time the wp option get home or wp option get siteurl changes
  • The code in the database (wp option get acf_pro_license) is more extensive than just the license code: It is a serialized field containing both the license code and the URL encoded in base64.

Example deciphering (code is slightly modified):

$ echo "YToyOntzOjM6ImtleSI7czo3MjoiTm1NNU16VTJOVFl3WVdetc.tIjtz12345678989CI7czoyN" | base64 -d

a:2:{s:3:"key";s:72:"123456etc.3NDRm";s:3:"url";s:19:"https://example.com";}

At the moment (2021.12.01) I don't need to automate this. In PHP this is at least doable, and with a wrapper function to call certain PHP functions from Bash, this can also be done from Bash. For more: https://anchor.host/preloading-advanced-custom-fields-pro-license-key/

See also

Sources