2

I was wondering if anyone could point me in the right direction.

We've got a custom plugin that we use with ExpressionEngine that connections to a 3rd party CMS system and grabs all relevant content from it and then inserts it into ExpressionEngine. I have need to expand the plugin to identify relating content and set the relationships inside ExpressionEngine.

From what I can gather, I would simply get the field_id from the exp_channel_fields for the relevant relationship channel field that has been created inside EE CP. I would then insert both the pieces of content (the main piece of content and the relating content) into exp_channel_data as usual, then get the entry_id's for both pieces of content.

Once I have the entry_id's, I can create a entry in exp_relationships, get the ID for the entry and then update exp_channel_data using the main piece of contents entry_id and setting the field_id_X, where X is the field ID I got at the beginning and the value being the relationship ID.

Assuming I have this all correct, the only thing I need to figure out is what rel_data in the exp_relationships table needs to be set to. It seems like some serialized object. I was wondering if there are classes that I could use to handle this for me?

Any help or pointers to the correct documentation would greatly be appreciated.

EDIT Did some digging, I think the function I am looking for is 'compile_relationship' inside the Functions class.

EDIT 2 It seems this function is being called when the following code is being run:

$this->EE->api_channel_entries->submit_new_entry($channel_id, $insert_data);

I'm guessing I need to format $insert_data with the correct fields in order to trigger the relationship insert. Will do some more digging.

2 Answers 2

4

From what I can gather, I would simply get the field_id from the exp_channel_fields for the relevant relationship channel field that has been created inside EE CP. I would then insert both the pieces of content (the main piece of content and the relating content) into exp_channel_data as usual, then get the entry_id's for both pieces of content.

Since EE 2 you don't need to worry about this as the Channels Entries API handles it for you.

http://ellislab.com/expressionengine/user-guide/development/api/api_channel_entries.html#submit-new-entry

DB Structure

You can do this manually and you are along the right lines. The exp_channel_fields table contains all the field and settings you configure through the CP, they're grouped by ID as listed in exp_field_groups. The actual data for each field type of each entry is stored in exp_channel_data.

The main data for each channel entry is stored across 2 tables (so not categories, member privileges etc). These tables are: exp_channel_titles and exp_channel_data. The titles table has all the base information for EE, title, date etc. The data table has all data as defined from your custom fields.

API

You could write all your own SQL calls or to make things easier use EEs DB class to write your own code get data into EE but the API handles everything for you!

In the docs eg:

$data = array(
        'title'         => 'Breaking News Story!',
        'entry_date'    => '1256953732',
        'edit_date'     => '1351653729',
        'field_id_6'    => 'Some data',
        'field_ft_6'    => 'none',
        'field_id_19'   => 'More data',
        'field_ft_19'   => 'xhtml'
);

You just need to provide an array of data for the API to insert the entry for you. field_id_6, where 6 is the ID of the field you created in EEs CP and can be found in exp_channel_fields. This has to be in the expected format for that fieldtype. Again you could query the exp_channel_fields table to determine which id relates to your named field but it's just as easy to make a note in your custom Add-on.

$query = $this->EE->db->query("SELECT field_id FROM exp_channel_fields WHERE field_name = 'my_field_name'");
if ($query->num_rows() > 0) $my_field_id = $results->row('field_id');
$data = array(
        'title'         => 'Breaking News Story!',
        'entry_date'    => '1256953732',
        'edit_date'     => '1351653729',
        'field_id_'.$my_field_id    => 'Some data'
);
3
  • 1
    Just a minor note: This code will break if the query fails to return records. If no records are returned $my_field_id will be unset and result in a PHP notice or error. Still the answer is correct, there would just need to be additional error tolerance in production ready code. Dec 19, 2012 at 18:38
  • This looks correct, but the two pieces of data are already in the DB, I just need to create the relationship between them, I've added the way I've done it below.
    – SynackSA
    Dec 20, 2012 at 9:21
  • I did spot that Justin! This is untested code to get SynackSA on the way. Assuming there's more than one field configured for the Channel I'd define all variables first and error check each db call in a custom method before running through the API. Error checking should be part of any code you write. Dec 20, 2012 at 21:41
2

I've managed to get it working with the following function below, which gets called after the main bit of data is inserted for the channel entry. It simply builds the relationship and then adds the relationship value to the correct field in exp_channel_data

public function add_cocktail_relationship($entry_id, $ccms_data) {

    if (isset($ccms_data['tags']) && !empty($ccms_data['tags'])) {
        // Loop through the tags and look for cocktails
        foreach($ccms_data['tags'] as $category) {
            if (preg_match('/COCKTAIL_/i', $category)) {
                $guid = preg_replace('/COCKTAIL_/i', '', $category);

                // get the relationship field id for 'recipe'
                $field_id = $this->EE->db->select('field_id')->get_where("exp_channel_fields", array('field_name' => 'recipe'))->row('field_id');

                // Get the entryID for the corresponding CCMS GUID
                $rel_entry_id = $this->EE->db->select('entry_id')->get_where("exp_ccms_content", array('guid' => $guid))->row('entry_id');

                if ($rel_entry_id && $entry_id && $rel_entry_id) {
                    $reldata = array(
                        'type'          => 'channel',
                        'parent_id'     => $entry_id,
                        'child_id'      => $rel_entry_id
                    );

                    $relationship_id = $this->EE->functions->compile_relationship($reldata, TRUE);

                    $channel_update = array (
                        "field_id_{$field_id}" => $relationship_id,
                        "field_ft_{$field_id}" => "none"
                    );

                    $this->EE->db->where('entry_id', $entry_id)->update("exp_channel_data", $channel_update);
                }   
                return;
            }
        }
    }
    return;
}
3
  • Glad you've got it working. The Channels API make this kind of stuff so much easier. Dec 20, 2012 at 21:43
  • @ElliotLewis How? I can't find any documentation for how to get the Channel Entries API to set/update relationships. Jul 15, 2014 at 21:15
  • ellislab.com/expressionengine/user-guide/development/api/… The docs state this is automatically handled. "submit_new_entry() and update_entry() will automatically recompile relationship data" Jul 17, 2014 at 7:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.