/** * Views-Shortcode: wpv-if * * Description: Conditional shortcode to be used to display a specific area * based on a custom field condition. \n * Supported actions and symbols:\n * Integer and floating-point numbers \n * Math operators: +, -, *, / \n * Comparison operators: <, >, =, <=, >=, != \n * Boolean operators: AND, OR, NOT \n * Nested expressions - several levels of parentheses \n * Variables defined as shortcode parameters starting with a dollar sign \n * empty() function that checks for empty or non-existing fields * * Parameters: * 'condition' => Define expected result from evaluate - either true or false * 'evaluate' => Evaluate expression with fields involved, sample use: "($field1 > $field2) AND !empty($field3)" * 'debug' => Enable debug to display error messages in the shortcode * 'fieldX' => Define fields to be taken into account during evaluation * * Example usage: * [wpv-if evaluate="boolean condition"] * Execute code for true * [/wpv-if] * Sing a variable and comparing its value to a constant * [wpv-if f1="wpcf-condnum1" evaluate="$f1 = 1" debug="true"]Number1=1[/wpv-if] * Two numeric variables in a mathematical expression with boolean operators * [wpv-if f1="wpcf-condnum1" f2="wpcf-condnum2" evaluate="(2 < 3 AND (((3+$f2)/2) > 3 OR NOT($f1 > 3)))" debug="true"]Visible block[/wpv-if] * Compare custom field with a value * [wpv-if f1="wpcf-condstr1" evaluate="$f1 = 'My text'" debug="true"]Text1='My text' [/wpv-if] * Display condition if evaluates to false (use instead of else-if) * [wpv-if condition="false" evaluate="2 > 3"] 2 > 3 [/wpv-if] * Custom function support * [wpv-if evaluate="my_func() = '1'"]my_func returns 1[/wpv-if] * * Link: * <a href="http://wp-types.com/documentation/user-guides/conditional-html-output-in-views/?utm_source=viewsplugin&utm_campaign=views&utm_medium=views-conditional-help-link&utm_term=Conditional HTML output in Views">Conditional HTML output in Views</a> * * Note: * */ function wpv_shortcode_wpv_if($args, $content) { $result = wpv_condition($args); extract(shortcode_atts(array('evaluate' => FALSE, 'debug' => FALSE, 'condition' => TRUE), $args)); $condition = $condition == 'true' || $condition === TRUE ? true : false; // show the view area if condition corresponds to the evaluate returned result 1=1 or 0=0 if ($result === true && $condition || $result === false && !$condition) { $out = wpv_do_shortcode($content); apply_filters('wpv_shortcode_debug', 'wpv-if', json_encode($args), '', 'Conditional output: evaluated to true', $out); return $out; } else { // output empty string or the error message if debug is true // empty for different condition and evaluate result if ($result === false && $condition || $result === true && !$condition) { apply_filters('wpv_shortcode_debug', 'wpv-if', json_encode($args), '', 'Conditional output: evaluated to false'); return ''; } else { if ($debug) { return $result; } else { return ''; } apply_filters('wpv_shortcode_debug', 'wpv-if', json_encode($args), '', 'Conditional output: error', $result); } } }
/** * 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; }
/** * 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; }
/** * 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 ($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; }