Skip to content

Instantly share code, notes, and snippets.

@notacouch
Created October 31, 2012 19:50
Show Gist options
  • Save notacouch/3989383 to your computer and use it in GitHub Desktop.
Save notacouch/3989383 to your computer and use it in GitHub Desktop.
ExpressionEngine get/strip "no_results" conditionals
/**
* @author Abed Islam
*
* Use and abuse to your liking.
*
* Needed a solution for "no_results"-like tags.
* (Where "no_results" can be customized to whatever tag you want.)
* Stephen Lewis of Experience Internet talks about it and provides a solution here:
* @link http://experienceinternet.co.uk/blog/ee-gotchas-nested-no-results-tags/
*
* But that would break if you so much as added another {if...}{/if} conditional
* within the custom {if no_results} {/if}. If that doesn't matter to you
* then you can refer to his sample add-on here:
* @link https://github.com/experience/no_results.ee_addon
*
* Otherwise read on.
*
* The following functions are simple but more effective ways of getting either
* the content within or outside of {if no_results}{/if} conditionals:
*
* get_simple_conditional($tagname, $tagdata);
* strip_simple_conditional($tagname, $tagdata);
*
* Some assumptions are made:
* -The conditional itself will not be used as an advanced conditional, e.g.
* WRONG: {if no_results}Not found{if:else}Found{/if}
* RIGHT: Found {if no_results}Not found{/if}
* -Your code is valid/well-written (there should be matching /if's to your if's!)
* -I forget what else
*
*/
// am too lazy to make a helper
if ( ! function_exists('strpos_recursive'))
{
/**
* Return positions of all occurences of needle in haystack
*
* Slightly modified from the original,
* returns key->value pair instead of just value
*
* @access public
* @param string
* @param string
* @param int
* @param array
* @return array
* @link http://php.net/manual/en/function.strpos.php#107678
*/
function strpos_recursive($haystack, $needle, $offset = 0, &$results = array())
{
$offset = strpos($haystack, $needle, $offset);
if($offset === false)
{
return $results;
}
else
{
$results[$offset] = $offset;
return strpos_recursive($haystack, $needle, ($offset + 1), $results);
}
}
} // end strpos_recursive
if ( ! function_exists('simple_conditional_positions'))
{
/**
* Function for finding start/end positions of no_results-like tagname conditionals
*
* @access public
* @param string conditional tag name e.g. no_results (please use something different)
* @param string subject/haystack to search in
* @return mixed tagdata if tagname not found, array pair of open tag positon => close tag position | k => v, sorted by k low to high
*/
function simple_conditional_positions($tagname = 'no_results', $tagdata = '')
{
if (empty($tagdata)) return $tagdata;
if (strpos($tagdata, '{if '.$tagname) === FALSE) return $tagdata;
$o1 = strpos_recursive($tagdata, '{if');
// there should be no if:else as a part of {if $tagname...
// if tag_name is meant as a simple conditional, a replacement for no_results
$o2 = strpos_recursive($tagdata, '{if:else');
$open_tags = array_diff($o1, $o2);
$close_tags = strpos_recursive($tagdata, '{/if}');
if (count($open_tags) != count($close_tags)) return $tagdata;
$pairs = array();
$open_tags_walk = $open_tags;
// Formula is something like
// Iterate through the close tags from left to right
// For each close tag sort between all values of open tag less than it
// The open/close pair is the max of the above
// remove the paired open tag from the pool of open tags
foreach ($close_tags as $key_c => $close_tag_position)
{
$temp = array();
foreach($open_tags_walk as $key_o => $open_tag_position)
{
// The moment the value is greater than we stop collecting
if ($open_tag_position >= $close_tag_position)
{
//unset($open_tags_walk[$key_o]);
break;
}
else
{
$temp[$open_tag_position] = $open_tag_position;
}
}
if ( ! empty($temp)) // should NOT be empty
{
$m = max($temp);
unset($open_tags_walk[$m]);
$pairs[$m] = $close_tag_position;
}
}
$tagname_open_tags = strpos_recursive($tagdata, '{if '.$tagname.'}');
// assume these are never nested in each other
$tagname_pairs = array_intersect_key($pairs, $tagname_open_tags);
ksort($tagname_pairs);
return $tagname_pairs;
}
}
if ( ! function_exists('get_simple_conditional'))
{
/**
* Return no_results-like conditional content
*
* @access public
* @param string tagname (default: no_results)
* @param string tagdata (default: empty)
* @return string
*/
function get_simple_conditional($tagname = 'no_results', $tagdata = '')
{
$tagname_pairs = simple_conditional_positions($tagname, $tagdata);
if ($tagname_pairs == $tagdata) return $tagdata;
// return what's in between {if tagname} and {/if}
$open_tag_length = strlen('{if '.$tagname.'}');
//$close_tag_length = 5;
$get = '';
foreach ($tagname_pairs as $open_tag_position => $close_tag_position)
{
$get .= substr($tagdata, $open_tag_position + $open_tag_length, $close_tag_position - ($open_tag_position + $open_tag_length));
}
return $get;
}
}
if ( ! function_exists('strip_simple_conditional'))
{
/**
* Return string with no_results-like conditionals removed
*
* @param string tagname (default: no_results)
* @param string tagdata (default: empty)
* @return string
*/
function strip_simple_conditional($tagname = 'no_results', $tagdata = '')
{
$tagname_pairs = simple_conditional_positions($tagname, $tagdata);
if ($tagname_pairs == $tagdata) return $tagdata;
// return what's outside of {if tagname}[...]{/if}
$open_tag_length = strlen('{if '.$tagname.'}');
$close_tag_length = 5;
$get = '';
$previous_close_tag_position = 0;
foreach ($tagname_pairs as $open_tag_position => $close_tag_position)
{
$get .= substr($tagdata, $previous_close_tag_position, $open_tag_position - $previous_close_tag_position);
$previous_close_tag_position = $close_tag_position + $close_tag_length;
}
return $get . substr($tagdata, $previous_close_tag_position);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment