/** * Editor callback form. */ function wpcf_fields_skype_editor_callback($field, $settings, $meta_type, $post) { // Get saved button style if any if ($meta_type == 'usermeta') { global $current_user; $_field = new WPCF_Usermeta_Field(); $_field->set($current_user->ID, $field); } else { $_field = new WPCF_Field(); $_field->set($post, $field); } $settings['button_style'] = isset($_field->meta['style']) ? $_field->meta['style'] : 'btn2'; return array('supports' => array('styling'), 'tabs' => array('display' => array('title' => __('Display options for this field:', 'wpcf'), 'menu_title' => __('Display options', 'wpcf'), 'content' => WPCF_Loader::template('skype-select-button', $settings)))); }
/** * Calls parent set func. * * @param type $post * @param type $field */ function set($post, $field) { parent::set($post, $field); $this->index = 0; }
/** * * Only for attachments, only default checkboxes! * * @internal breakpoint * @param type $post_ID * @param type $post */ function wpcf_admin_post_add_attachment_hook($post_ID, $post) { global $wpcf; /** * Basic check: only attachment */ if ('attachment' != $post->post_type) { return false; } /** * Get all groups connected to this $post */ $groups = wpcf_admin_post_get_post_groups_fields($post); if (empty($groups)) { return false; } $all_fields = array(); $_not_valid = array(); $_error = false; /** * Loop over each group * * TODO Document this * Connect 'wpcf-invalid-fields' with all fields */ foreach ($groups as $group) { if (isset($group['fields'])) { // Process fields $fields = wpcf_admin_post_process_fields($post, $group['fields'], true, false, 'validation'); // Validate fields $form = wpcf_form_simple_validate($fields); $all_fields = $all_fields + $fields; // Collect all not valid fields if ($form->isError()) { $_error = true; // Set error only to true $_not_valid = array_merge($_not_valid, (array) $form->get_not_valid()); } } } // Set fields foreach ($all_fields as $k => $v) { // only Types field if (empty($v['wpcf-id'])) { continue; } $_temp = new WPCF_Field(); $_temp->set($wpcf->post, $v['wpcf-id']); $all_fields[$k]['_field'] = $_temp; } foreach ($_not_valid as $k => $v) { // only Types field if (empty($v['wpcf-id'])) { continue; } $_temp = new WPCF_Field(); $_temp->set($wpcf->post, $v['wpcf-id']); $_not_valid[$k]['_field'] = $_temp; } /** * Process all checkbox fields */ foreach ($all_fields as $field) { /** * only checkbox */ if (!isset($field['#type']) || 'checkbox' != $field['#type']) { continue; } $field_data = wpcf_admin_fields_get_field($field['wpcf-id']); /** * check is checked for new! */ $checked = array_key_exists('checked', $field_data['data']) && $field_data['data']['checked']; /** * do not save empty and not checked? fine, go away... */ if ('no' == $field_data['data']['save_empty'] && !$checked) { continue; } /** * all other just save... */ $update_data = 0; if ($checked) { $update_data = $field_data['data']['set_value']; } add_post_meta($post_ID, wpcf_types_get_meta_prefix($field) . $field['wpcf-slug'], $update_data); } do_action('wpcf_attachement_add', $post_ID); }
function wpcf_fields_checkbox_update_one($post_id, $slug, $array_to_check) { $cf = new WPCF_Field(); $cf->set($post_id, $cf->__get_slug_no_prefix($slug)); /** * return if field do not exists */ if (!array_key_exists('data', $cf->cf)) { return; } if ('checkbox' == $cf->cf['type']) { if (isset($array_to_check[$cf->__get_slug_no_prefix($slug)]) || isset($array_to_check[$slug])) { update_post_meta($post_id, $slug, $cf->cf['data']['set_value']); return; } $cf->set($post_id, $cf->__get_slug_no_prefix($slug)); if ($cf->cf['data']['save_empty'] != 'no') { update_post_meta($post_id, $cf->slug, 0); } else { delete_post_meta($post_id, $cf->slug); } } else { if ('checkboxes' == $cf->cf['type']) { $value = array(); if (isset($array_to_check[$cf->__get_slug_no_prefix($slug)])) { foreach ($array_to_check[$cf->__get_slug_no_prefix($slug)] as $key => $val) { if (isset($cf->cf['data']['options'])) { $value[$key] = $val; } } } update_post_meta($post_id, $cf->slug, $value); } } }
/** * Filters conditional display value for built-in Types Conditinal check. * * @param type $value * @param type $field * @param type $operation * @param type $conditional_field * @param type $post * @return type */ function wpcf_fields_date_conditional_value_filter($value, $field, $operation, $field_compared, $post) { $field = wpcf_admin_fields_get_field($field); if (!empty($field) && $field['type'] == 'date') { /* * * * * * Here we need to determine data */ $_field = new WPCF_Field(); $_field->set($post, $field); return wpcf_fields_date_value_get_filter($value, $_field, 'timestamp', 'skip_hour_and_minute'); // TODO Date revise why needed. // Check dates $value = wpv_filter_parse_date($value); } return $value; }
function set($post, $cf) { parent::set($post, $cf); // Check and record call $this->fields[$this->slug] = $this->passed = $this->evaluate(); }
/** * Important save_post hook. * * Core function. Works and stable. Do not move or change. * If required, add hooks only. * * @internal breakpoint * @param type $post_ID * @param type $post */ function wpcf_admin_post_save_post_hook($post_ID, $post) { global $wpcf; // Basic cheks /* * Allow this hook to be triggered only if Types form is submitted */ if (!isset($_POST['_wpcf_post_wpnonce']) || !wp_verify_nonce($_POST['_wpcf_post_wpnonce'], 'update-' . $post->post_type . '_' . $post_ID)) { return false; } /* * Do not save post if is type of: * revision * attachment * wp-types-group * view * view-template * cred-form */ if (in_array($post->post_type, $wpcf->excluded_post_types)) { return false; } /* * * * Get all groups connected to this $post */ $groups = wpcf_admin_post_get_post_groups_fields($post); if (empty($groups)) { return false; } $all_fields = array(); $_not_valid = array(); $_error = false; /* * * * Loop over each group * * TODO Document this * Connect 'wpcf-invalid-fields' with all fields */ foreach ($groups as $group) { // Process fields $fields = wpcf_admin_post_process_fields($post, $group['fields'], true, false, 'validation'); // Validate fields $form = wpcf_form_simple_validate($fields); $all_fields = $all_fields + $fields; // Collect all not valid fields if ($form->isError()) { $_error = true; // Set error only to true $_not_valid = array_merge($_not_valid, (array) $form->get_not_valid()); } } // Set fields foreach ($all_fields as $k => $v) { // only Types field if (empty($v['wpcf-id'])) { continue; } $_temp = new WPCF_Field(); $_temp->set($wpcf->post, $v['wpcf-id']); $all_fields[$k]['_field'] = $_temp; } foreach ($_not_valid as $k => $v) { // only Types field if (empty($v['wpcf-id'])) { continue; } $_temp = new WPCF_Field(); $_temp->set($wpcf->post, $v['wpcf-id']); $_not_valid[$k]['_field'] = $_temp; } /* * * Allow interaction here. * Conditional will set $error to false if field is conditional * and not submitted. */ $error = apply_filters('wpcf_post_form_error', $_error, $_not_valid, $all_fields); $not_valid = apply_filters('wpcf_post_form_not_valid', $_not_valid, $_error, $all_fields); // Notify user about error if ($error) { wpcf_admin_message_store(__('Please check your input data', 'wpcf'), 'error'); } /* * Save invalid elements so user can be informed after redirect. */ if (!empty($not_valid)) { update_post_meta($post_ID, 'wpcf-invalid-fields', $not_valid); } /* * * * * * Save meta fields */ if (!empty($_POST['wpcf'])) { foreach ($_POST['wpcf'] as $field_slug => $field_value) { // Get field by slug $field = wpcf_fields_get_field_by_slug($field_slug); if (empty($field)) { continue; } // Set field $wpcf->field->set($post_ID, $field); // Skip copied fields // CHECKPOINT if (isset($_POST['wpcf_repetitive_copy'][$field['slug']])) { continue; } // Don't save invalid // CHECKPOINT if (isset($not_valid[$field['slug']])) { continue; } /* * * * Saving fields * @since 1.2 * * We changed way repetitive fields are saved. * On each save fields are rewritten and order is saved in * '_$slug-sort-order' meta field. */ /* * * We marked fields as repetitive in POST['__wpcf_repetitive'] * Without this check we won't save any. * @see WPCF_Repeater::get_fields_form() */ if (isset($_POST['__wpcf_repetitive'][$wpcf->field->slug])) { /* * Use here WPCF_Repeater class. * WPCF_Repeater::set() - switches to current post * WPCF_Repeater::save() - saves repetitive field */ $wpcf->repeater->set($post_ID, $field); $wpcf->repeater->save(); } else { /* * Use WPCF_Field::save() */ $wpcf->field->save(); } do_action('wpcf_post_field_saved', $post_ID, $field); } } /* * Process checkboxes * * TODO Revise and remove * Since Types 1.1.5 we moved this check to embedded/includes/checkbox.php * checkbox.php added permanently to bootstrap. */ foreach ($all_fields as $field) { if (!isset($field['#type'])) { continue; } // if ( $field['#type'] == 'checkbox' // && !isset( $_POST['wpcf'][$field['wpcf-slug']] ) ) { // $field_data = wpcf_admin_fields_get_field( $field['wpcf-id'] ); // if ( isset( $field_data['data']['save_empty'] ) // && $field_data['data']['save_empty'] == 'yes' ) { // update_post_meta( $post_ID, // wpcf_types_get_meta_prefix( $field ) . $field['wpcf-slug'], // 0 ); // } else { // delete_post_meta( $post_ID, // wpcf_types_get_meta_prefix( $field ) . $field['wpcf-slug'] ); // } // } if ($field['#type'] == 'checkboxes') { $field_data = wpcf_admin_fields_get_field($field['wpcf-id']); if (!empty($field_data['data']['options'])) { $update_data = array(); foreach ($field_data['data']['options'] as $option_id => $option_data) { if (!isset($_POST['wpcf'][$field['wpcf-slug']][$option_id])) { if (isset($field_data['data']['save_empty']) && $field_data['data']['save_empty'] == 'yes') { $update_data[$option_id] = 0; } } else { $update_data[$option_id] = $_POST['wpcf'][$field['wpcf-slug']][$option_id]; } } update_post_meta($post_ID, wpcf_types_get_meta_prefix($field) . $field['wpcf-slug'], $update_data); } } } do_action('wpcf_post_saved', $post_ID); }
/** * Main conditinal evaluation function. * * This is important break-point. * * @since 1.2 * @version 0.1 * @param type $o * @return boolean */ function evaluate($o) { // Set vars $post = $o->post; $field = $o->cf; /* * * Since Types 1.2 * We force initial value to be FALSE. * Better to have restricted than allowed because of sensitive data. * If conditional is set on field and it goes wrong - better to abort * so user can report bug without exposing his content. */ $passed = false; if (empty($post->ID)) { /* * * Keep all forbidden if post is not saved. */ $passed = false; /* * * * * * * * * * * VIEWS * * Custom call uses Views code * wpv_filter_parse_date() * wpv_condition() */ } else { if (isset($field['data']['conditional_display']['custom_use'])) { /* * * * More malformed forbids */ if (empty($field['data']['conditional_display']['custom'])) { return false; } /* * * * Filter meta values (switch them with $_POST values) * Used by Views, Types do not need it. */ add_filter('get_post_metadata', 'wpcf_cd_meta_ajax_validation_filter', 10, 4); /* * * Set statement */ $evaluate = trim(stripslashes($field['data']['conditional_display']['custom'])); // Check dates $evaluate = wpv_filter_parse_date($evaluate); // Add quotes = > < >= <= === <> !== $strings_count = preg_match_all('/[=|==|===|<=|<==|<===|>=|>==|>===|\\!===|\\!==|\\!=|<>]\\s(?!\\$)(\\w*)[\\)|\\$|\\W]/', $evaluate, $matches); if (!empty($matches[1])) { foreach ($matches[1] as $temp_match) { $temp_replace = is_numeric($temp_match) ? $temp_match : '\'' . $temp_match . '\''; $evaluate = str_replace(' ' . $temp_match . ')', ' ' . $temp_replace . ')', $evaluate); } } preg_match_all('/\\$([^\\s]*)/', $field['data']['conditional_display']['custom'], $matches); if (empty($matches)) { /* * * If statement false */ $passed = false; } else { /* * * * If statement right, check condition */ $fields = array(); foreach ($matches[1] as $field_name) { /* * * * This field value is checked */ $f = wpcf_admin_fields_get_field(trim(strval($field_name))); if (empty($f)) { return false; } $c = new WPCF_Field(); $c->set($post, $f); // Set field $fields[$field_name] = $c->slug; } $fields['evaluate'] = $evaluate; $check = wpv_condition($fields); /* * * * Views return string malformed, * boolean if call completed. */ if (!is_bool($check)) { $passed = false; } else { $passed = $check; } } /* * * * Remove filter meta values */ remove_filter('get_post_metadata', 'wpcf_cd_meta_ajax_validation_filter', 10, 4); } else { /* * * * * * * * * * TYPES * * If not custom code, use Types built-in check. * wpcf_cd_admin_compare() */ $passed_all = true; $passed_one = false; // Basic check if (empty($field['data']['conditional_display']['conditions'])) { return false; } // Keep count to see if OR/AND relation needed $count = count($field['data']['conditional_display']['conditions']); foreach ($field['data']['conditional_display']['conditions'] as $condition) { /* * * * Malformed condition and should be treated as forbidden */ if (!isset($condition['field']) || !isset($condition['operation']) || !isset($condition['value'])) { $passed_one = false; continue; } /* * * * This field value is checked */ $f = wpcf_admin_fields_get_field(trim(strval($condition['field']))); if (empty($f)) { return false; } $c = new WPCF_Field(); $c->set($post, $f); /* * * Since Types 1.2 * meta is property of WPCF_Field::$__meta * * BREAKPOINT * This is where values for evaluation are set. * Please do not allow other places - use hooks. */ $value = defined('DOING_AJAX') ? $c->_get_meta('POST') : $c->__meta; /* * * Apply filters */ $value = apply_filters('wpcf_conditional_display_compare_meta_value', $value, $c->cf['id'], $condition['operation'], $c->slug, $post); $condition['value'] = apply_filters('wpcf_conditional_display_compare_condition_value', $condition['value'], $c->cf['id'], $condition['operation'], $c->slug, $post); /* * * * Call built-in Types compare func */ $passed = wpcf_cd_admin_compare($condition['operation'], $value, $condition['value']); if (!$passed) { $passed_all = false; } else { $passed_one = true; } } /* * * * Check OR/AND relation */ if ($count > 1) { if (!$passed_all && $field['data']['conditional_display']['relation'] == 'AND') { $passed = false; } if (!$passed_one && $field['data']['conditional_display']['relation'] == 'OR') { $passed = false; } } } } return (bool) $passed; }
function set($post, $cf) { parent::set($post, $cf); }
/** * Check if checkbox is submitted. * * Currently used on Relationship saving. May be expanded to general code. * * @param type $value * @param type $field * @param type $cf */ function wpcf_fields_checkbox_save_check() { $meta_to_unset = array(); $cf = new WPCF_Field(); /* * * We hve several calls on this: * 1. Saving post with Update * 2. Saving all children * 3. Saving child */ $mode = 'save_main'; if (defined('DOING_AJAX')) { if (isset($_GET['wpcf_action']) && $_GET['wpcf_action'] == 'pr_save_all') { $mode = 'save_all'; } else { if (isset($_GET['wpcf_action']) && $_GET['wpcf_action'] == 'pr_save_child_post') { $mode = 'save_child'; } } } // See if any marked for checking if (isset($_POST['_wpcf_check_checkbox'])) { // Loop and search in $_POST foreach ($_POST['_wpcf_check_checkbox'] as $child_id => $slugs) { foreach ($slugs as $slug => $true) { $cf->set($child_id, $cf->__get_slug_no_prefix($slug)); // First check main post if ($mode == 'save_main' && intval($child_id) == wpcf_get_post_id()) { if (!isset($_POST['wpcf'][$cf->cf['slug']])) { $meta_to_unset[intval($child_id)][$cf->slug] = true; } continue; } /* * * Relationship check */ if (!isset($_POST['wpcf_post_relationship'])) { $meta_to_unset[$child_id][$cf->slug] = true; } else { foreach ($_POST['wpcf_post_relationship'] as $_parent => $_children) { foreach ($_children as $_child_id => $_slugs) { if (!isset($_slugs[$slug])) { $meta_to_unset[$_child_id][$cf->slug] = true; } } } } } } } // After collected - delete them foreach ($meta_to_unset as $child_id => $slugs) { foreach ($slugs as $slug => $true) { $cf->set($child_id, $cf->__get_slug_no_prefix($slug)); if ($cf->cf['data']['save_empty'] != 'no') { update_post_meta($child_id, $slug, 0); } else { delete_post_meta($child_id, $slug); } } } }
/** * Parses date meta. * * @param type $value * @param type $field Field data * @return type */ function wpcf_fields_date_value_get_filter($value, $field) { global $wpcf; if (is_array($value)) { /* * Since Types 1.2 */ $value = wp_parse_args($value, array('datepicker' => null, 'hour' => 8, 'minute' => 0)); } else { /* * We assume it is timestamp from earlier versions */ $value = array('datepicker' => $value, 'hour' => 8, 'minute' => 0); } /* * Since Types 1.2 we require $cf field object */ if ($field instanceof WPCF_Field) { $post = $field->post; } else { // Remove for moment remove_filter('wpcf_fields_type_date_value_get', 'wpcf_fields_date_value_get_filter', 10, 4); // Hide on frontpage where things will go fine because of loop if (is_admin()) { _deprecated_argument('date_obsolete_parameter', '1.2', '<br /><br /><div class="wpcf-error">' . 'Since Types 1.2 $cf field object is required' . '</div><br /><br />'); } /* * Set default objects */ $_field = $field; $field = new WPCF_Field(); $field->context = is_admin() ? 'frontend' : 'group'; $post_id = wpcf_get_post_id($field->context); $post = get_post($post_id); if (empty($post)) { return $value; } $field->set($post, $_field); // Back to filter add_filter('wpcf_fields_type_date_value_get', 'wpcf_fields_date_value_get_filter', 10, 4); } /* * * Get hour and minute * CHECKPOINT * * We need meta_id here. */ if (!empty($post->ID)) { $_meta_id = isset($_field['__meta_id']) ? $_field['__meta_id'] : $field->meta_object->meta_id; $_hm = get_post_meta($post->ID, '_wpcf_' . $field->cf['id'] . '_hour_and_minute', true); $hm = isset($_hm[$_meta_id]) ? $_hm[$_meta_id] : array(); } else { /* * If $post is not set. * We need to record this */ $wpcf->errors['missing_post'][] = func_get_args(); } /* * Setup hour and minute. */ if (!empty($hm) && is_array($hm) && (isset($hm['hour']) && isset($hm['minute']))) { $value['hour'] = $hm['hour']; $value['minute'] = $hm['minute']; } // Calculate time $value['timestamp'] = wpcf_fields_date_calculate_time($value); // Set datepicker to use formatted date if (!empty($value['datepicker'])) { // Test if already formatted if (strtotime($value['datepicker']) === false) { $value['datepicker'] = date(wpcf_get_date_format(), intval($value['datepicker'])); } } return $value; }
/** * Parses date meta. * * Use this as main function. * * @uses wpcf_fields_date_calculate_time() * * @param type $value * @param type $field Field data * $param string $return Specify to return array or specific element of same array * ( timestamp, datepicker, hour, minute ) * @return mixed array | custom parameter */ function wpcf_fields_date_value_get_filter($value, $field, $return = 'array', $context = 'get') { global $wpcf; $value_cloned = $value; if (is_array($value)) { /* * See if missing timestamp and datepicker present */ if ((!isset($value['timestamp']) || !is_int($value['timestamp'])) && isset($value['datepicker'])) { $_check = strtotime(strval($value['datepicker'])); if ($_check !== false) { $value['timestamp'] = $_check; } } $value = wp_parse_args($value, array('timestamp' => null, 'hour' => 8, 'minute' => 0, 'datepicker' => '')); } else { if (empty($value)) { return array('timestamp' => null, 'hour' => 8, 'minute' => 0, 'datepicker' => ''); } else { /* * strtotime() returns negative numbers like -49537390513 * * https://icanlocalize.basecamphq.com/projects/7393061-toolset/todo_items/160422568/comments * http://www.php.net/manual/en/function.strtotime.php * * QUOTE * Returns a timestamp on success, FALSE otherwise. * Previous to PHP 5.1.0, this function would return -1 on failure. * * BUT on some hosts it returns negative numbers ( our test sites too ) */ if (!is_numeric($value)) { $_check = strtotime($value); if ($_check !== false && $_check > 1) { $value = $_check; } } $value = array('timestamp' => intval($value), 'hour' => 8, 'minute' => 0, 'datepicker' => ''); } } $value['datepicker'] = trim($value['datepicker']); /* * Since Types 1.2 we require $cf field object */ if ($field instanceof WPCF_Field) { $post = $field->post; } else { // Remove for moment remove_filter('wpcf_fields_type_date_value_get', 'wpcf_fields_date_value_get_filter', 10, 4); // Hide on frontpage where things will go fine because of loop if (is_admin()) { _deprecated_argument('date_obsolete_parameter', '1.2', '<br /><br /><div class="wpcf-error">' . 'Since Types 1.2 $cf field object is required' . '</div><br /><br />'); } /* * Set default objects */ $_field = $field; $field = new WPCF_Field(); $field->context = is_admin() ? 'frontend' : 'group'; $post_id = wpcf_get_post_id($field->context); $post = get_post($post_id); if (empty($post)) { return $value; } $field->set($post, $_field); // Back to filter add_filter('wpcf_fields_type_date_value_get', 'wpcf_fields_date_value_get_filter', 10, 4); } /* * Get hour and minute * We need meta_id here. * * NOT Used for 'save' context. * We already have submitted data in $value */ if (!in_array($context, array('save', 'skip_hour_and_minute'))) { if (!empty($post->ID)) { $_meta_id = isset($_field['__meta_id']) ? $_field['__meta_id'] : $field->meta_object->meta_id; $_hm = get_post_meta($post->ID, '_wpcf_' . $field->cf['id'] . '_hour_and_minute', true); $hm = isset($_hm[$_meta_id]) ? $_hm[$_meta_id] : array(); } else { /* * If $post is not set. * We need to record this */ $wpcf->errors['missing_post'][] = func_get_args(); } /* * Setup hour and minute. */ if (!empty($hm) && is_array($hm) && (isset($hm['hour']) && isset($hm['minute']))) { $value['hour'] = $hm['hour']; $value['minute'] = $hm['minute']; } } // Calculate time IF NOT SET ( otherwise it's same as main meta value ) // Always when using 'get' context on frontend if (!is_admin() && $context == 'get' || (empty($value['timestamp']) || !is_int($value['timestamp']))) { $value['timestamp'] = wpcf_fields_date_calculate_time($value); } /* * Set datepicker to use formatted date IF DO NOT EXISTS * (otherwise it keeps Datepicker string like 'August 9, 2012'. * OR is not time string */ if (!empty($value['timestamp']) && (empty($value['datepicker']) || strtotime(strval($value['datepicker'])) === false)) { $value['datepicker'] = date(wpcf_get_date_format(), intval($value['timestamp'])); } $_return = $value; if ($return != 'array') { if (isset($value[strval($return)])) { $_return = $value[strval($return)]; } } // Debug $wpcf->debug->dates[] = array('original_value' => $value_cloned, 'value' => $value, 'return' => $_return, 'field' => $field->cf, 'context' => $context); return $_return; }