Why won't the Import plugin accept this JSON string? Importing data.csv using Bob Olde Hampsink's Import plugin. Given that data.csv has a 'table' item string thusly:

"Alcohol and Drug Treatment:RX-8450.3300,Counseling:RP-1400.8000-145,Mental Health Services:RR-5150.1500,Support Groups:PNPH-8100.4500-050"


(two columns, four rows. dead simple)

Lindsay tells us here that: 


  a table field contains a simple JSON string


So we are writing a plugin using Import's modifyImportRow hook and here's what we have in the hook loop:

...
// Arrange your content in a way that makes sense for your plugin
foreach ($fields as $handle =&gt; $value) {

    if ($handle=="myTableHandle"){

      $rows = explode(',', $value);

      $tabledata = array();

      foreach ($rows as $row) {
        $rowarray = explode(':',$row);

        $rowdata['col1'] = $rowarray[0];
        $rowdata['col2'] = $rowarray[1];

        $tabledata[] = $rowdata;
      }

      $value = json_encode($tabledata);

   }

   $content[$handle] = $value;

}
...


The import works, but the table field data (myTableHandle) remains NULL.

What else can we do to that string of table data to get the Import plugin to accept?
You're close!

The method that Lindsey recommends should work with the following method of adding content to a field:

$entry-&gt;getContent()-&gt;setAttributes(array(
    'tableFieldHandle' =&gt; json_encode($tableData)
));


However, the modifyImportRow documentation uses the (arguably better) method:

// Set modified content
$element-&gt;setContentFromPost($content);


Using this method, you should add an array to a table field, rather than a JSON strong, since setContentFromPost() will call the relevant methods to format the field data appropriately for the database, so you don't need to worry about it.

So if you use:

$content[$handle] = $tabledata;


then add it to the element using:

// Set modified content
$element-&gt;setContentFromPost($content);


it should work.



The full code for the modifyImportRow function in your plugin should now look like this:

/**
 * Modify data just before importing
 *
 * @param BaseElementModel $element  The current element receiving import data.
 * @param array            $map      Mapping of data between CSV -&gt; Craft fields.
 * @param array            $data     Raw data provided for this row.
 */
public function modifyImportRow($element, $map, $data)
{
    // Map data to fields
    $fields = array_combine($map, $data);

    // Initialize content array
    $content = array();

    // Arrange your content in a way that makes sense for your plugin
    foreach ($fields as $handle =&gt; $value) {

        if ($handle=="myTableHandle"){

            $rows = explode(',', $value);

            $tabledata = array();

            foreach ($rows as $row) {
                $rowarray = explode(':',$row);

                $rowdata['col1'] = $rowarray[0];
                $rowdata['col2'] = $rowarray[1];

                $tabledata[] = $rowdata;
            }

        }

        $content[$handle] = $tabledata;

    }

    // Set modified content
    $element-&gt;setContentFromPost($content);
}