Support

Account

Home Forums General Issues How to Upgrade Simple Fields to ACF 5

Solving

How to Upgrade Simple Fields to ACF 5

  • I recently had to update some sites from the discontinued Simple Fields plugin to ACF. I hope this might help someone.

    The steps below are non-destructive, nothing is deleted. This process duplicates your Simple Fields data to a format that ACF 5 uses. It’s up to you to go and clean up the old Simple Fields data from your database if you wish. Please test on a non-production site first to get working!

    Step By Step

    1. Create a new ACF field group that matches the old Simple Fields group. ACF stores information about the new fields in the wp_posts table. You don’t need to mess with this. What we will be doing is migrating your Simple Field data over to a format the ACF recognizes. This will happen in the wp_postmeta table.
    2. You should now have two similar looking Field Group boxes in your content type editing screen.
    3. Now you need to track down the Simple Field names. They are in the format “_simple_fields_fieldGroupID_1_fieldID_1_numInSet_0”. Each field group is a unique integer and each field within each group is also a unique integer. You can run an SQL query like ‘SELECT meta_key,meta_value FROM wp_postmeta where meta_key LIKE ‘%simple_field%’;’. This should show you all your Simple Field’s keys and values.
    4. For each Simple Field we’ll need to grab every Post ID and the actual value of the field.
    5. Then using this data we’ll insert two new rows of data for every matching ACF field.
    6. It’s probably best to do steps 4 and 5 with code. I’ve included some sample starter code below of how to extract the Simple Field info and create two new rows of field data for ACF to use. Certainly power users could implement everything in a monster sql query.
    7. Important – Update all your template and perhaps function.php code to use ACF to retrieve custom field data. Ideally you should have this done and ready to implement before you migrate the data.
    8. Disable Simple Fields plugin and clean up Simple Fields rows from your database if you wish.

    
    /*** Sample PHP Code ***/
    
    /* Simple Fields to ACF Migrator */
    
    // PDO Database Connection
    $dsn = "mysql:host=your-host-here;dbname=your-database-name-here";
    $user = "your-db-username";
    $passwd = "your-db-password";
    
    $pdo = new PDO($dsn,$user,$passwd);
    
    // SQL for Selecting all the existing Simple Field data. Each query is field. I put them in an array so we can iterate through them. 
    // Example below is for three custom Simple Fields that form one field group. Substitute your field names for the values.
    // There are two sub select statements in these queries that use the new ACF field name and also grab its machine name. Important - This is where you match each Simple Field to its new ACF counterpart.
    $simple_fields = array(
    	"SELECT post_id, meta_value, (SELECT post_excerpt from {$wp_posts} WHERE post_excerpt = 'acf_field_1' AND post_type = 'acf-field') AS acffieldname, (SELECT post_name from {$wp_posts} WHERE post_excerpt = 'acf_field_1' AND post_type = 'acf-field') AS acfrealfieldname FROM {$wp_postmeta} WHERE meta_key = '_simple_fields_fieldGroupID_1_fieldID_1_numInSet_0'",
    	"SELECT post_id, meta_value, (SELECT post_excerpt from {$wp_posts} WHERE post_excerpt = 'acf_field_2' AND post_type = 'acf-field') AS acffieldname, (SELECT post_name from {$wp_posts} WHERE post_excerpt = 'acf_field_2' AND post_type = 'acf-field') AS acfrealfieldname FROM {$wp_postmeta} WHERE meta_key = '_simple_fields_fieldGroupID_1_fieldID_2_numInSet_0'",
    	"SELECT post_id, meta_value, (SELECT post_excerpt from {$wp_posts} WHERE post_excerpt = 'acf_field_3' AND post_type = 'acf-field') AS acffieldname, (SELECT post_name from {$wp_posts} WHERE post_excerpt = 'acf_field_3' AND post_type = 'acf-field') AS acfrealfieldname FROM {$wp_postmeta} WHERE meta_key = '_simple_fields_fieldGroupID_1_fieldID_3_numInSet_0'"
    );
    
    // Iterate over each field executing its select query to grab the data, and pass it to a function to insert the two new rows of ACF data
    foreach ($simple_fields as $field) {
    	$rows = updateSimpleFieldsToAcf($pdo,$field);
    }
    
    // Simple function to take each field's data and insert into wp_postmeta in ACF format
    function updateSimpleFieldsToAcf($pdo,$sql) {
    
    	// Prepare and execute each field's sql statement.
    	$stm = $pdo->prepare($sql);
    	$stm->execute();
    	
    	// grab all the rows in an array, we will now iterate over each of these rows and insert our two new rows
    	$rows = $stm->fetchAll(PDO::FETCH_ASSOC);
    	// Our basic sql statement for inserting the new data
    	// Remember if you're on WordPress multisite or externally hosted your table names may have an integer prefix, e.g. wp_13_postmeta
    	$sql1 = "INSERT INTO wp_postmeta (<code>post_id</code>,<code>meta_key</code>,<code>meta_value</code>) VALUES (?,?,?)";
    	
    	// Iterate over each row and perfom two inserts
    	foreach($rows as $row) {
    		// You can clean up or manipulate the selected data here and place in variables to insert. 
    		$row_post_id = $row['post_id']; // post id
    		$row_field_name = $row['acffieldname']; // acf field name
    		$u_row_field_name = "_" . $field_name; // acf field name prepended with underscore
    		$row_clean_value = $row['meta_value']; // actual value of field, may need to clean up character encoding or such here.
    		$row_real_field_name = $row['acfrealfieldname']; // machine name of acf field e.g. field_5d94f173d6daa
    		
    		// First row insert - post_id, field_name, cleaned meta_value
    		//$sql_first_row = "INSERT INTO {$q_tablename} (<code>post_id</code>,<code>meta_key</code>,<code>meta_value</code>) VALUES (<code>{$row['post_id']}</code>, <code>{$field_name}</code>, <code>{$clean_value}</code>)";
    		$stm1 = $pdo->prepare($sql1);
    		$stm1->bindValue(1, $row_post_id, PDO::PARAM_INT);
    		$stm1->bindValue(2, $row_field_name, PDO::PARAM_STR);
    		$stm1->bindValue(3, $row_clean_value, PDO::PARAM_STR);
    		$result = $stm1->execute(); // should implement some error checking on your result e.g. if (!$result) check $stm1->errorInfo etc.
    		
    		//$sql_second_row = "INSERT INTO {$q_tablename} (<code>post_id</code>,<code>meta_key</code>,<code>meta_value</code>) VALUES (<code>{$row['post_id']}</code>, <code>{$u_field_name}</code>, <code>{$row['acfrealfieldname']}</code>)";
    		$stm2 = $pdo->prepare($sql1);
    		$stm2->bindValue(1, $rpw_post_id, PDO::PARAM_INT);
    		$stm2->bindValue(2, $u_row_field_name, PDO::PARAM_STR);
    		$stm2->bindValue(3, $row_real_field_name, PDO::PARAM_STR);
    		$result = $stm2->execute(); // again, no error checking
    	}
    }
    
    /* End Sample Code */
    

    SUMMARY – It’s moderately easy to migrate all your data and fields from Simple Fields to ACF. You first duplicate the fields groups in ACF. Then select the existing Simple Fields one by one and match the field and data with its new ACF counterpart. Using this data, you create two new rows of data in the postmeta table that’s in a fromat ACF recognizes. Your new ACF fields will automatically use the new field values. Don’t forget you have to update your template code to call the ACF fields instead of Simple Fields. You can also delete the rows of Simple Field data if you are so inclined.

  • Hello John or other users who know something about this topic,

    I have some questions regarding the solution described to migrate from Simple Fields to ACF5 fields.
    First of all: does this solution still work?

    Then: a long time ago I worked as a COBOL-programmer and I managed to execute step 1, 2 and 3 myself. But I fear steps 4 and 5 are too complicated for me.
    Is it possible to fill the new ACF5 fields manually? We (a travel agency) use Simple Fields to show extra information for every sample tour we offer (like day-to-day-itinerary, customer review, tips, see e.g. https://www.blinireizen.nl/reizen/georgie-commpleet/, left sidebar). We have 85 tours, with a maximum of 3 fields per tour, so it can be done manually without much effort.

    My last 2 questions concern step 7:
    How do you know in which templates and function.php Simple Fields is used? A simple search doesn’t seem to work.
    How should I call the AFC 5 function? It’s with the same parameters as for Simple Fields?
    An example from single-travel.php (which displays the left sidebar) is:
    $meta_schema = simple_fields_get_post_value($post->ID, “travel schedule”, true);

    Thanks, any help is welcome.

    Irene de Jonge
    Blini Reizen
    Netherlands

  • I’m sorry, but I can’t really help hare. This requires understanding how both custom field plugins store values. I’m also not familiar with what the OP used to do the conversions. Maybe the OP will reply and give you input.

  • Irene,
    You should definitely just update your site to ACF manually. Your success rate is 100% with this method as opposed to trying to use a very technical approach that requires knowledge of PHP, SQL, and the guts of WordPress. It’s probably not worth the hours of effort to automate the migration when you can just re-enter the values.

    To find the templates where Simple Fields was used you may want to search using terms from here:
    https://simple-fields.com/documentation/api/getting-values/index.html
    This was how most people retrieved simple fields and displayed them on their site. It all depends on what theme you’re using and how many templates there are.

    ACF has similar functionality:
    https://www.advancedcustomfields.com/resources/get_field/
    This is how you retrieve and display custom fields using ACF.

    First you need to create the new fields using ACF and enter the data. Then you would swap one retrieve and display method for the other in your theme’s templates.

    Good luck.
    John

  • I would have to agree with @johnbarneson

    You’re talking about rebuilding all of the templates and moving content. It will rarely be cost effective to make the change automatically or creating a import tool to do this when it will happen exactly 1 time. My experience is that it will take longer to build the tool, make sure it work and then use it than it will take so simply update the data manually.

    If I had to do this on a budget and the number of fields was extremely limited I would

    1) Create my new acf field groups.

    2) At each location where a “simple field” was used I would see if the acf field has content and if not then use the existing simple fields code

    
    if (get_field('some-field')) {
      // data exists in the new acf field
    } else {
      // no data in acf field
      // existing simple fields code here
    }
    

    3) The next step I would take is to add an acf/prepare_field filter for every acf field that needed to use the simple fields data. In this field I would test for a value in the field. If there is no value then I would get the simple fields field value. What this does it that it will copy any existing data when and if someone edits an old page.

    4) As an added step I would create an acf/save+post action that deletes all the data stored by simple fields whenever a post us updated.

  • Hi John & John,

    Thank you for your last posts (I forgot to check the Notify box and only saw your replies this week…)
    I will transfer the contents of the SF-fields manually into ACF-fields.

    1) I have created a new ACF-group field, with the same fields and names as the SF-group field
    You can see 3 of the fields on the left side of the page https://www.blinireizen.nl/reizen/georgie-compleet/. Georgia Complete is one of the 84 example-programs we offer, the template for every example tour is the same. The fields REISSCHEMA (fieldname=reisschema), REVIEWS & REiSVERSLAGEN (fieldname=reactie), BLINI TIP (fieldname=tip) and SOCIAL MEDIA (fieldname=FB_photo).

    2) I have filled one ACF-group field manually, with the same contents as the corresponding SF-group.

    3) I have located the theme and all php-files where the SF-function is used (fortunately not that many).

    4) I have started adjusting the most important php-file (in which the left bar of the mentioned page is filled). BUt unfortunately I got stuck here. The current code says:

    <?php
    $meta_schema = simple_fields_get_post_value($post->ID, “reisschema”, true);
    $tip = simple_fields_get_post_value($post->ID, “tip”, true);
    $reactie = simple_fields_get_post_value($post->ID, “reactie”, true);
    $FB_photo = simple_fields_value(“FB_photo”);
    $FB_photo = apply_filters(“the_content”, $FB_photo);
    ?>

    I started with only 1 field and replaced the second line with:
    $tip = get_field($post->ID, “tip”, true);
    if( $value ) {
    echo $value;
    } else {
    echo ’empty’;
    }

    When testing, it says ’empty’. Probably I can’t use the parameter $post->ID in the same way as is done in the SF-function, but I can’t find in the ADCF-documentation how it should be done.

    Two questions:
    * can you tell me how to fill this parameter (I assume this refers to the number of the post, e.g. number 78 of our example programs.
    * If you can’t help me, could you advise me where to post this question? I think for someone who knows php this won’t be very difficult to solve.

    By the way, fortunately we also have a test-environment, so nothing can go wrong when trying.

    Thanks again!

  • Hello BliniReizen,
    The parameters of ACF get_field() are as follows:
    get_field($selector, [$post_id], [$format_value]);

    So your test code should look like this:

    $tip = get_field("tip",$post->ID);
    if( $tip ) {
        echo $tip;
    } else {
        echo ’empty’;
    }

    Give this a try. The third parameter is true by default ($format_value).
    Thanks,
    John

  • Hi John,

    Great, it works!!!!!

    I’ve filled the fields ‘tip’, ‘reactie’ and ‘metaschema’.
    Next I’ll try the other php-functions that are using SF.
    The ‘FB_photo’ is less important, so I’ll wait with that till the other fields are solved.
    A question: should I make posts like this Public or Private?

    Thanks again for your help,
    Irene

    FYI: the SF-field ‘metaschema’ is in our current website filled as below.
    When I copy-paste this to the corresponding ACF-field, it looses the returns after each day and displays as one long line
    (for the moment I’ve added <br /> in between each day).
    Dag 1-2: Tbilisi
    Dag 3: Kakheti
    Dag 4: Mtskheta, Stepantsminda
    Dag 5: Stepantsminda: Gergeti, Sno-vallei
    Dag 6: Uplistsikhe, Gori
    Dag 7: Chiatura, Kutaisi
    Dag 8: Svaneti: Mestia
    Dag 9: Mestia: Ushguli
    Dag 10-11: Batoemi
    Dag 12: Prometheus, Tskaltubo, Kutaisi
    Dag 13: Borjomi, Akhaltsikhe, Vardzia
    Dag 14: Vardzia, Tbilisi
    Dag 15: thuisreis

  • Hi John,

    I just wanted to let you know that as of yesterday our website works with Advanced Custom Fields instead of Simple Fields. With your help I was able to transfer the contents of all fields. Thanks again!

Viewing 9 posts - 1 through 9 (of 9 total)

The topic ‘How to Upgrade Simple Fields to ACF 5’ is closed to new replies.