We use cookies to improve your experience. No personal information is gathered and we don't serve ads. Cookies Policy.

ExpressionEngine Logo ExpressionEngine
Features Pricing Support Find A Developer
Partners Upgrades
Blog Add-Ons Learn
Docs Forums University
Log In or Sign Up
Log In Sign Up
ExpressionEngine Logo
Features Pro new Support Find A Developer
Partners Upgrades
Blog Add-Ons Learn
Docs Forums University Blog
  • Home
  • Forums

Custom Form Module - How Do I Create Channel Entries?

Development and Programming

nicholaswyoung's avatar
nicholaswyoung
23 posts
14 years ago
nicholaswyoung's avatar nicholaswyoung

In an earlier post I asked if SafeCracker could handle multiple pieces of form data and create multiple entries from a single form post. Since the answer was ‘no’, I’ve decided to write my own module.

However, I don’t fully understand how the Channels API works - hopefully someone can explain. Here’s what I need to do:

Create a form that contains multiple elements (think an array):

<input name='ingredients[]' type='text' />

I want my module to see this array and insert each entry into a set channel.

For the most part, I understand form parsing, and how to create the outside form tags. What I don’t understand is how I create an entry for each element in the array.

       
nicholaswyoung's avatar
nicholaswyoung
23 posts
14 years ago
nicholaswyoung's avatar nicholaswyoung

Update:

During my research, I ran across the submit_new_entry method. However, I don’t quite understand how the example works. Something seems to be missing, even though the example seems to have come from the moblog module, which I know is part of EE Core.

Specific Questions

  • Where did the first usage of $data come from? Are there two variables defined with the same name?

Example (from the fourth line of code in the submit_new_entry code sample):

$this->EE->api_channel_fields->setup_entry_settings($data['channel_id'], $data);

This returns an undefined variable error. What’s up?

  • What do the keys like ‘field_id_6’ mean?

  • Running something like this (see below) doesn’t work. Is it because I ignored these special keys?

$this->EE->load->library('api');
  $this->EE->api->instantiate('channel_entries');
  $this->EE->api->instantiate('channel_fields');
  
  $data = array(
   'title' => 'Testing',
   'address1' => 'P.O. Box 0444040',
   'line1' => 'Just for you.',
   'entry_date' => time(),
   'channel_id' => 8
  );
  
  $this->EE->api_channel_fields->setup_entry_settings($data['channel_id'], $data);
  
  if($this->EE->api_channel_entries->submit_new_entry($data['channel_id'], $data) === FALSE) {
   show_error("something went wrong, but we don't know what.");
  }
       
nicholaswyoung's avatar
nicholaswyoung
23 posts
14 years ago
nicholaswyoung's avatar nicholaswyoung

Okay - I’ve figured this much out…

public function labels_form_submit() {
  $this->EE->load->library('form_validation');
  $this->EE->load->library('api');
  
  $this->EE->form_validation->set_rules('labels[contact_name]', 'Contact Name', 'required');
  $this->EE->form_validation->set_rules('labels[address1]', 'Address 1', 'required');
  $this->EE->form_validation->set_rules('labels[city_name]', 'City', 'required');
  $this->EE->form_validation->set_rules('labels[state_name]', 'State', 'required');
  $this->EE->form_validation->set_rules('labels[zip_code]', 'Zipcode', 'required');
  $this->EE->form_validation->set_rules('labels[1][line1]', 'Label 1, Line 1', 'required');
  
  if($this->EE->form_validation->run() == FALSE) {
   $this->EE->session->set_flashdata('error', 'Validation failed. Please resubmit with all of the required fields.')
   $this->EE->functions->redirect($this->EE->functions->create_url('/labels'));
  } else {
   $this->EE->api->instantiate('channel_entries');
   $this->EE->api->instantiate('channel_fields');
   $channel_fields = $this->_get_fields();
   $form_fields = $_POST['labels'];

   $base_fields = array(
    $channel_fields['contact name']['key'] => $form_fields['contact_name'],
    $channel_fields['address1']['key'] => $form_fields['address1'],
    $channel_fields['city_name']['key'] => $form_fields['city_name'],
    $channel_fields['state_name']['key'] => $form_fields['state_name'],
    $channel_fields['zip_code']['key'] => $form_fields['zip_code']
   );
   
   unset($form_fields['contact_name']);
   unset($form_fields['address1']);
   unset($form_fields['address2']);
   unset($form_fields['city_name']);
   unset($form_fields['state_name']);
   unset($form_fields['zip_code']);
   
   foreach($form_fields as $key => $val) {
    $guid = $this->_generate_uniq_id($base_fields);
    $entry = array(
     'channel_id' => $this->channel_id,
     $channel_fields['line1']['key'] => $val['line1'],
     $channel_fields['line2']['key'] => $val['line2'],
     'title' => 'Label ' . $guid,
     'entry_date' => time()
    );
    $merged = array_merge($base_fields, $entry);
    if ($this->EE->api_channel_entries->submit_new_entry($this->channel_id, $merged) === FALSE) { 
     $errors = $this->EE->api_channel_entries->errors;
     show_error('An Error Occurred Creating the Entry: <pre>' . print_r( $errors, true ) . '</pre>

<p>’);
    } else {
     $this->EE->functions->redirect($this->EE->functions->create_url(‘/labels/thanks’));
    }
   }
  }
 }
</pre>

But when running the above code (if I’m not logged in as an admin), I get:

An Error Was Encountered
You are not authorized to post in this channel.

What should I do to get around this?

UPDATE:

1: The

$merged

variable from above looks like this. Hopefully, this clears up any confusion:

Array ( 
[field_id_22] => Nicholas [
field_id_18] => P.O. Box 
[field_id_23] => Chicago 
[field_id_25] => IL 
[field_id_24] => 606060 
[channel_id] => 8 
[field_id_20] => TEST LINE 1 
[field_id_21] => TEST LINE 2 
[title] => Label 93ce372b7103b73296cafa4e2a529150cafb2e6c 
[entry_date] => 1318435231 )

The data in this array satisfies my custom required fields.

2: I thought that maybe I should provide the

$this->_get_fields();

function as well:

private function _get_fields() {
  $this->EE->api->instantiate('channel_fields');
  $arr = $this->EE->api_channel_fields->setup_entry_settings($this->channel_id, array());
  $newArr = array();
  foreach($arr as $key => $val) {
   if(is_array($val) && $val['field_label']) {
    $newArr[$val['field_label']] = array(
     'key' => $key,
     'id' => $val['field_id'],
     'type' => $val['field_type'],
     'required' => $val['field_required']
    );
   }
  }
  return $newArr;
 }

This is just a quick way to lookup the field_id’s in a friendly manner.

       
nicholaswyoung's avatar
nicholaswyoung
23 posts
14 years ago
nicholaswyoung's avatar nicholaswyoung

Bump.

I’ve posted some cleaner code above, and looked around the forums for an answer. This seems to have been a bug at one time, but everything seems to be solved.

Have we created a new bug in the process of fixing the old one?

       
Marcus Neto's avatar
Marcus Neto
1,005 posts
14 years ago
Marcus Neto's avatar Marcus Neto

I need you to be specific about what you are trying to accomplish. It is not clear from this post. It seems like you may be misunderstanding how to use safecracker from your:

- What do the keys like ‘field_id_6’ mean?

comment.

Also you commented on twitter about something that has been documented not working in this version? What is not working?

We want to help so just clarify these items and I’ll try to answer.

       
nicholaswyoung's avatar
nicholaswyoung
23 posts
14 years ago
nicholaswyoung's avatar nicholaswyoung
I need you to be specific about what you are trying to accomplish. It is not clear from this post. It seems like you may be misunderstanding how to use safecracker from your:
What do the keys like ‘field_id_6’ mean?
comment.

As evidenced by the later posts in this thread, I’ve moved past the first issue. I’m no longer considering SafeCracker - from what I’ve gathered, it is not a viable option.

From what I can tell the only problem I’m currently facing is the “you’re not allowed to post in this channel” error when I’m not logged in as an admin.

Also you commented on twitter about something that has been documented not working in this version? What is not working?

This is a separate issue, and probably shouldn’t be addressed in this thread. However, I’ll mention it briefly:

When defining file upload destinations and manipulations on uploaded files, the short field that I define doesn’t seem to work properly.

Once we’ve remedied the main problem (with my custom module), then we’ll move on to the other one. It’s of lesser importance, but the presence of it in the docs - when it wasn’t working, and was in a released version - was frustrating to say the least.

       
Marcus Neto's avatar
Marcus Neto
1,005 posts
14 years ago
Marcus Neto's avatar Marcus Neto

My previous tweet about a checkbox was in regards to safecracker and since you have stated that you have moved past that then ignore that tweet.

Have you looked at safecracker’s method for getting around this issue? If you are looking for code examples that might be the best way to go.

Why are you not wanting to use Safecracker? Seems like if you are wanting to enter content into a channel it would be easier to create an extension that breaks up the content into various entries vs starting all over again reinventing functionality that safecracker already provides….

       
nicholaswyoung's avatar
nicholaswyoung
23 posts
14 years ago
nicholaswyoung's avatar nicholaswyoung
Why are you not wanting to use Safecracker? Seems like if you are wanting to enter content into a channel it would be easier to create an extension that breaks up the content into various entries vs starting all over again reinventing functionality that safecracker already provides….

Whoa. I’ve looked at SafeCracker, and been told numerous times that it didn’t satisfy my requirements. But, for a moment, let’s explore that option. Here’s what I require:

  • A form that submits:

    • A field with the user’s name, email address, physical address, and an array of entries (and their custom fields) all in a single form post.
  • A backend (be it SafeCracker, or a custom module) that stores each of the array of entries, and inputs the shipping details (from the first part of the form) in along with each post.

    • (I have a channel called Submissions, where we have fields for all of the user’s submitted information, and then custom fields that relate to each entry. So, for example, we would have: contact_name, address_line_1, address_line_2, city, state, zip - and then line_1, and line_2. The last two are fields that are submitted as the array of entries.

In short, I’m looking to create multiple entries with a single form post. I’ve been told repeatedly that this is not a feature offered by SafeCracker. Was the advice I was given correct, or can SafeCracker do what I require?

       
Marcus Neto's avatar
Marcus Neto
1,005 posts
14 years ago
Marcus Neto's avatar Marcus Neto

You have been told correctly that SafeCracker will not allow you to create multiple entries from a single post. I didn’t say that. What I did say was that you can probably find another way around this.

For instance, a simple way around this would be to have 2 pages that get filled out. Page 1 would be the first entry and page 2 would contain the second. When user x files in page 1 have it return to page 2 and be filled in. Or you could do a tabbed page that has the two.

The second way of handling this would be more difficult but still easier than recreating safecracker would be to create an extension to safecracker that allows for multiple entries. That way all of your session handling and heavy lifting are handled by safecracker.

I am also curious of why you have to have separate entries for what appears to be demographic data. Couldn’t that all just be in a single entry?

Understand we are just riffing some ideas here….

       
nicholaswyoung's avatar
nicholaswyoung
23 posts
14 years ago
nicholaswyoung's avatar nicholaswyoung
For instance, a simple way around this would be to have 2 pages that get filled out. Page 1 would be the first entry and page 2 would contain the second. When user x files in page 1 have it return to page 2 and be filled in. Or you could do a tabbed page that has the two. The second way of handling this would be more difficult but still easier than recreating safecracker would be to create an extension to safecracker that allows for multiple entries. That way all of your session handling and heavy lifting are handled by safecracker.

I still think there’s something wrong here - because I shouldn’t be getting this error. But, as long as I get to the destination, I don’t mind if the bug exists, so long as it isn’t in my way.

However, I’m open to either idea. Can you describe how I might go about these two approaches? Code samples and documentation would be helpful.

I am also curious of why you have to have separate entries for what appears to be demographic data. Couldn’t that all just be in a single entry?

I sent you a PM with details of what I’m working on. Hopefully, it clears up the picture for you.

       
Andrew Weaver's avatar
Andrew Weaver
206 posts
14 years ago
Andrew Weaver's avatar Andrew Weaver

The channel entries api requires you to be logged in and have permission to post entries to a channel to work.

If you are logged in as a Super admin does running your script work?

If so, it is possible to “fake” a login within the add-on - I think the LogMeIn plugin does this: http://devot-ee.com/add-ons/logmein

Andrew

       
nicholaswyoung's avatar
nicholaswyoung
23 posts
14 years ago
nicholaswyoung's avatar nicholaswyoung
If you are logged in as a Super admin does running your script work?

Yes, it does. Can the add-on you posted enable this for guest users (or even for users of other groups)?

       
Andrew Weaver's avatar
Andrew Weaver
206 posts
14 years ago
Andrew Weaver's avatar Andrew Weaver

I think something like this:

// If not currently logged in, create a dummy session
  if( $this->EE->session->userdata['member_id'] == 0) {
   $this->EE->session->create_new_session(1, TRUE);
   $this->EE->session->userdata['group_id']  = 1;
   $this->EE->session->userdata['can_edit_other_entries'] = 'y';
   $this->EE->session->userdata['can_delete_self_entries'] = 'y';
   $this->EE->session->userdata['can_delete_all_entries'] = 'y';
  }

will give your add-on Super-admin (group=1) permissions.

Andrew

       
Marcus Neto's avatar
Marcus Neto
1,005 posts
14 years ago
Marcus Neto's avatar Marcus Neto

Nicholas,

The add-on Andrew mentioned does give member groups the ability post without having a log in. If a user is logged in then you could just give that member group permission to post to the channel in question and you will be ok.

       
nicholaswyoung's avatar
nicholaswyoung
23 posts
14 years ago
nicholaswyoung's avatar nicholaswyoung
…it is possible to “fake” a login within the add-on - I think the LogMeIn plugin does this: http://devot-ee.com/add-ons/logmein Andrew

Andrew, you rock. Not only did you deliver the final blow to this problem, but your DataGrab add-on saved me a TON of time earlier on this project.

If you’re ever in Chicago, I totally owe you a beer.

       
1 2

Reply

Sign In To Reply

ExpressionEngine Home Features Pro Contact Version Support
Learn Docs University Forums
Resources Support Add-Ons Partners Blog
Privacy Terms Trademark Use License

Packet Tide owns and develops ExpressionEngine. © Packet Tide, All Rights Reserved.