/** * 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; }
/** * Filters groups on post edit page. * * @param type $groups * @param type $post * @return type */ function wpcf_cd_post_groups_filter($groups, $post, $context) { if ($context != 'group') { return $groups; } foreach ($groups as $key => &$group) { $meta_conditional = !isset($group['conditional_display']) ? get_post_meta($group['id'], '_wpcf_conditional_display', true) : $group['conditional_display']; if (!empty($meta_conditional['conditions'])) { $group['conditional_display'] = $meta_conditional; add_action('admin_head', 'wpcf_cd_add_group_js'); if (empty($post->ID)) { $group['_conditional_display'] = 'failed'; continue; } $passed = true; if (isset($group['conditional_display']['custom_use'])) { if (empty($group['conditional_display']['custom'])) { $group['_conditional_display'] = 'failed'; continue; } $evaluate = trim(stripslashes($group['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]*)/', $group['conditional_display']['custom'], $matches); if (empty($matches)) { $group['_conditional_display'] = 'failed'; continue; } $fields = array(); foreach ($matches[1] as $key => $field_name) { $fields[$field_name] = wpcf_types_get_meta_prefix(wpcf_admin_fields_get_field($field_name)) . $field_name; wpcf_cd_add_group_js('add', $field_name, '', '', $group['id']); } $fields['evaluate'] = $evaluate; $check = wpv_condition($fields); $passed = $check; if (!is_bool($check)) { $passed = false; $group['_conditional_display'] = 'failed'; } else { if ($check) { $group['_conditional_display'] = 'passed'; } else { $group['_conditional_display'] = 'failed'; } } } else { $passed_all = true; $passed_one = false; foreach ($group['conditional_display']['conditions'] as $condition) { // Load field $field = wpcf_admin_fields_get_field($condition['field']); wpcf_fields_type_action($field['type']); wpcf_cd_add_group_js('add', $condition['field'], $condition['value'], $condition['operation'], $group['id']); $value = get_post_meta($post->ID, wpcf_types_get_meta_prefix($condition['field']) . $condition['field'], true); $value = apply_filters('wpcf_conditional_display_compare_meta_value', $value, $condition['field'], $condition['operation'], $key, $post); $condition['value'] = apply_filters('wpcf_conditional_display_compare_condition_value', $condition['value'], $condition['field'], $condition['operation'], $key, $post); $check = wpcf_cd_admin_compare($condition['operation'], $value, $condition['value']); if (!$check) { $passed_all = false; } else { $passed_one = true; } } if (!$passed_all && $group['conditional_display']['relation'] == 'AND') { $passed = false; } if (!$passed_one && $group['conditional_display']['relation'] == 'OR') { $passed = false; } } if (!$passed) { $group['_conditional_display'] = 'failed'; } else { $group['_conditional_display'] = 'passed'; } } } return $groups; }
/** * Checks if there is conditional display. * * @param type $element * @param type $field * @param type $post * @return type */ function wpcf_cd_post_edit_field_filter($element, $field, $post, $context = 'group') { if (defined('DOING_AJAX') && $context == 'repetitive') { return $element; } if (!empty($field['data']['conditional_display']['conditions'])) { add_action('admin_head', 'wpcf_cd_add_field_js'); $passed = true; if (empty($post->ID)) { $passed = false; } else { if (isset($field['data']['conditional_display']['custom_use'])) { if (empty($field['data']['conditional_display']['custom'])) { return array(); } $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)) { $passed = false; } else { $fields = array(); foreach ($matches[1] as $key => $field_name) { $fields[$field_name] = wpcf_types_get_meta_prefix(wpcf_admin_fields_get_field($field_name)) . $field_name; } $fields['evaluate'] = $evaluate; $check = wpv_condition($fields); if (!is_bool($check)) { $passed = false; } else { $passed = $check; } } } else { $passed_all = true; $passed_one = false; foreach ($field['data']['conditional_display']['conditions'] as $condition) { // This is malformed condition and should be treated as passed // @TODO Approve it if (!isset($condition['field']) || !isset($condition['operation']) || !isset($condition['value'])) { $passed_one = true; continue; } $value = get_post_meta($post->ID, wpcf_types_get_meta_prefix($condition['field']) . $condition['field'], true); $value = apply_filters('wpcf_conditional_display_compare_meta_value', $value, $condition['field'], $condition['operation'], $field['slug'], $post); $condition['value'] = apply_filters('wpcf_conditional_display_compare_condition_value', $condition['value'], $condition['field'], $condition['operation'], $field['slug'], $post); $check = wpcf_cd_admin_compare($condition['operation'], $value, $condition['value']); if (!$check) { $passed_all = false; } else { $passed_one = true; } } if (!$passed_all && $field['data']['conditional_display']['relation'] == 'AND') { $passed = false; } if (!$passed_one && $field['data']['conditional_display']['relation'] == 'OR') { $passed = false; } } } if (!$passed) { $wrap = '<div class="wpcf-cd wpcf-cd-failed" style="display:none;">'; $element['__wpcf_cd_status'] = 'failed'; } else { $wrap = '<div class="wpcf-cd wpcf-cd-passed">'; $element['__wpcf_cd_status'] = 'passed'; } if (isset($element['#before'])) { $element['#before'] = $wrap . $element['#before']; } else { $element['#before'] = $wrap; } if (isset($element['#after'])) { $element['#after'] = $element['#after'] . '</div>'; } else { $element['#after'] = '</div>'; } } return $element; }
/** * Checks if there is conditional display. * * @param type $element * @param type $field * @param type $post * @return type */ function wpcf_cd_post_edit_field_filter($element, $field, $post, $context = 'group') { if ($context != 'group') { return $element; } if (!empty($field['data']['conditional_display']['conditions'])) { if (empty($post)) { return array(); } $passed = true; if (isset($field['data']['conditional_display']['custom_use'])) { if (empty($field['data']['conditional_display']['custom'])) { return array(); } preg_match_all('/\\$([^\\s]*)/', $field['data']['conditional_display']['custom'], $matches); if (empty($matches)) { return array(); } $fields = array(); foreach ($matches[1] as $key => $field_name) { $fields[$field_name] = wpcf_types_get_meta_prefix(wpcf_admin_fields_get_field($field_name)) . $field_name; } $fields['evaluate'] = trim($field['data']['conditional_display']['custom']); $check = wpv_condition($fields); if (!is_bool($check)) { return array(); } $passed = $check; } else { $passed_all = true; $passed_one = false; foreach ($field['data']['conditional_display']['conditions'] as $condition) { $value = get_post_meta($post->ID, wpcf_types_get_meta_prefix($condition['field']) . $condition['field'], true); $check = wpcf_cd_admin_compare($condition['operation'], $value, $condition['value']); if (!$check) { $passed_all = false; } else { $passed_one = true; } } if (!$passed_all && $field['data']['conditional_display']['relation'] == 'AND') { $passed = false; } if (!$passed_one && $field['data']['conditional_display']['relation'] == 'OR') { $passed = false; } } if (!$passed) { return array(); } } return $element; }