/** * Prints a form to the end user so that the users on the front-end can create * posts (beware security!). * * [cctm_post_form post_type="property" thank_you_url="" on_save="default-action-here"] * * @param array $raw_args: parameters from the shortcode: name, filter * @param string $options (optional) * @return string (printed) */ public static function cctm_post_form($raw_args = array(), $options = null) { $post_type = CCTM::get_value($raw_args, 'post_type'); $output = array('content' => '', 'errors' => ''); $defaults = array('post_type' => '', 'post_status' => 'draft', 'post_author' => CCTM::get_user_identifier(), 'post_date' => date('Y-m-d H:i:s'), 'post_date_gmt' => gmdate('Y-m-d H:i:s'), 'post_modified' => date('Y-m-d H:i:s'), 'post_modified_gmt' => gmdate('Y-m-d H:i:s'), '_label_title' => __('Title'), '_label_content' => __('Content'), '_label_excerpt' => __('Excerpt'), '_callback_pre' => null, '_callback' => 'CCTM::post_form_handler', '_action' => get_permalink(), '_tpl' => '_default', '_id_prefix' => 'cctm_', '_name_prefix' => 'cctm_', '_css' => CCTM_URL . '/css/manager.css,' . CCTM_URL . '/css/validation.css', '_fields' => '', '_debug' => 0); $args = array_merge($defaults, $raw_args); // Call the _callback_pre function (if present). if ($args['_callback_pre']) { if (function_exists($args['_callback_pre'])) { $output['content'] .= call_user_func($args['_callback_pre'], $args); } else { return '_callback_pre function does not exist: ' . $args['_callback_pre']; } } // Load CSS $css = explode(',', $args['_css']); foreach ($css as $c) { $css_id = basename($c); wp_register_style($css_id, $c); wp_enqueue_style($css_id); } // Hard error if (empty($post_type)) { return __('cctm_post_form shortcode requires the "post_type" parameter.', CCTM_TXTDOMAIN); } elseif (in_array($post_type, array('attachment', 'revision', 'nav_menu_item'))) { return sprintf(__('cctm_post_form shortcode does not support that post_type: %s', CCTM_TXTDOMAIN), $post_type); } // WTF? if (!post_type_exists($post_type)) { return sprintf(__('cctm_post_form shortcode post_type not found: %s', CCTM_TXTDOMAIN), $post_type); } //------------------------------ // Process the form on submit //------------------------------ $nonce = CCTM::get_value($_POST, '_cctm_nonce'); if (!empty($_POST)) { // Bogus submission if (!wp_verify_nonce($nonce, 'cctm_post_form_nonce')) { die('Your form could not be submitted. Please reload the page and try again.'); } // Strip prefix from post keys: only collect those with the given prefix. // This should allow mulitiple forms on one page. $vals = array(); foreach ($_POST as $k => $v) { if (preg_match('/^' . preg_quote($args['_name_prefix']) . '/', $k)) { $k = preg_replace('/^' . preg_quote($args['_name_prefix']) . '/', '', $k); $vals[$k] = wp_kses($v, array()); // TODO: options for this? } } // Validate fields StandardizedCustomFields::validate_fields($post_type, $vals); $vals = array_merge($vals, $args); if ($args['_debug']) { print '<div style="background-color:orange; padding:10px;"><h3>[cctm_post_form] DEBUG MODE</h3>' . '<h4>Posted Data</h4><pre>' . print_r($vals, true) . '</pre>' . '</div>'; return; } // Save data if it was properly submitted if (empty(CCTM::$post_validation_errors)) { return call_user_func($args['_callback'], $vals); } else { $error_item_tpl = CCTM::load_tpl(array('forms/_error_item.tpl')); $hash = array(); $hash['errors'] = ''; $hash['error_msg'] = __('This form has validation errors.', CCTM_TXTDOMAIN); $hash['cctm_url'] = CCTM_URL; foreach (CCTM::$post_validation_errors as $k => $v) { $hash['errors'] .= CCTM::parse($error_item_tpl, array('error' => $v)); } $error_wrapper_tpl = CCTM::load_tpl(array('forms/_error_wrapper.tpl')); $output['errors'] = CCTM::parse($error_wrapper_tpl, $hash); } } //------------------------------ // Generate the form. //------------------------------ $output['_action'] = $args['_action']; // Custom fields $explicit_fields = false; $custom_fields = array(); if ($args['_fields']) { $explicit_fields = true; $tmp = explode(',', $args['_fields']); foreach ($tmp as $t) { $custom_fields[] = trim($t); } $args['_fields'] = $custom_fields; } elseif (isset(CCTM::$data['post_type_defs'][$post_type]['custom_fields'])) { $custom_fields = CCTM::$data['post_type_defs'][$post_type]['custom_fields']; } // Post Title if (!$explicit_fields && post_type_supports($args['post_type'], 'title') && !isset($args['post_title']) || $explicit_fields && in_array('post_title', $custom_fields)) { $FieldObj = CCTM::load_object('text', 'fields'); $post_title_def = array('label' => $args['_label_title'], 'name' => 'post_title', 'default_value' => wp_kses(CCTM::get_value($_POST, $args['_name_prefix'] . 'post_title'), array()), 'extra' => '', 'class' => '', 'description' => '', 'validator' => '', 'output_filter' => '', 'type' => 'text'); $FieldObj->set_props($post_title_def); $output_this_field = $FieldObj->get_create_field_instance(); $output['post_title'] = $output_this_field; $output['content'] .= $output_this_field; } // Post Content (editor) if (!$explicit_fields && post_type_supports($args['post_type'], 'editor') && !isset($args['post_content']) || $explicit_fields && in_array('post_content', $custom_fields)) { $FieldObj = CCTM::load_object('textarea', 'fields'); // TODO: change to wysiwyg $post_title_def = array('label' => $args['_label_content'], 'name' => 'post_content', 'default_value' => wp_kses(CCTM::get_value($_POST, $args['_name_prefix'] . 'post_content'), array()), 'extra' => 'cols="80" rows="10"', 'class' => '', 'description' => '', 'validator' => '', 'output_filter' => '', 'type' => 'textarea'); $FieldObj->set_props($post_title_def); $output_this_field = $FieldObj->get_create_field_instance(); $output['post_content'] = $output_this_field; $output['content'] .= $output_this_field; } // Post Excerpt if (!$explicit_fields && post_type_supports($args['post_type'], 'excerpt') && !isset($args['post_excerpt']) || $explicit_fields && in_array('post_excerpt', $custom_fields)) { $FieldObj = CCTM::load_object('textarea', 'fields'); $post_title_def = array('label' => $args['_label_excerpt'], 'name' => 'post_excerpt', 'default_value' => wp_kses(CCTM::get_value($_POST, $args['_name_prefix'] . 'post_excerpt'), array()), 'extra' => 'cols="80" rows="10"', 'class' => '', 'description' => '', 'validator' => '', 'output_filter' => '', 'type' => 'textarea'); $FieldObj->set_props($post_title_def); $output_this_field = $FieldObj->get_create_field_instance(); $output['post_excerpt'] = $output_this_field; $output['content'] .= $output_this_field; } foreach ($custom_fields as $cf) { // skip the field if its value is hard-coded if (!isset(CCTM::$data['custom_field_defs'][$cf]) || isset($args[$cf])) { continue; } $def = CCTM::$data['custom_field_defs'][$cf]; if (isset($def['required']) && $def['required'] == 1) { $def['label'] = $def['label'] . '*'; // Add asterisk } // SECURITY OVERRIDES!!! // See https://code.google.com/p/wordpress-custom-content-type-manager/wiki/cctm_post_form if ($def['type'] == 'wysiwyg') { $def['type'] = 'textarea'; } elseif (in_array($def['type'], array('relation', 'image', 'media'))) { $output['errors'] .= ' ' . $def['type'] . ' fields not allowed.'; continue; } $output_this_field = ''; if (!($FieldObj = CCTM::load_object($def['type'], 'fields'))) { continue; } // Repopulate if (isset($_POST[$args['_name_prefix'] . $def['name']])) { $def['default_value'] = wp_kses($_POST[$args['_name_prefix'] . $def['name']], array()); } if (empty(CCTM::$post_validation_errors)) { $FieldObj->set_props($def); $output_this_field = $FieldObj->get_create_field_instance(); } else { $current_value = wp_kses(CCTM::get_value($_POST, $args['_name_prefix'] . $def['name']), array()); if (isset(CCTM::$post_validation_errors[$def['name']])) { $def['error_msg'] = sprintf('<span class="cctm_validation_error">%s</span>', CCTM::$post_validation_errors[$def['name']]); if (isset($def['class'])) { $def['class'] .= 'cctm_validation_error'; } else { $def['class'] = 'cctm_validation_error'; } } $FieldObj->set_props($def); $output_this_field = $FieldObj->get_edit_field_instance($current_value); } $output[$cf] = $output_this_field; $output['content'] .= $output_this_field; } // Add Nonce $output['nonce'] = '<input type="hidden" name="_cctm_nonce" value="' . wp_create_nonce('cctm_post_form_nonce') . '" />'; $output['content'] .= $output['nonce']; // Add Submit $output['submit'] = '<input type="submit" value="' . __('Submit', CCTM_TXTDOMAIN) . '" />'; $output['content'] .= $output['submit']; $formtpl = CCTM::load_tpl(array('forms/' . $args['_tpl'] . '.tpl', 'forms/_' . $post_type . '.tpl', 'forms/_default.tpl')); if ($args['_debug']) { $formtpl = '<div style="background-color:orange; padding:10px;"><h3>[cctm_post_form] DEBUG MODE</h3>' . '<h4>Arguments</h4><pre>' . print_r($args, true) . '</pre>' . '</div>' . $formtpl; } return CCTM::parse($formtpl, $output); }