public static function sec($cx, $v, $bp, $in, $each, $cb, $else = null)
{
$push = $in !== $v || $each;
$isAry = is_array($v) || $v instanceof \ArrayObject;
$isTrav = $v instanceof \Traversable;
$loop = $each;
$keys = null;
$last = null;
$isObj = false;
if ($isAry && $else !== null && count($v) === 0) {
$ret = $else($cx, $in);
return $ret;
}
// #var, detect input type is object or not
if (!$loop && $isAry) {
$keys = array_keys($v);
$loop = count(array_diff_key($v, array_keys($keys))) == 0;
$isObj = !$loop;
}
if ($loop && $isAry || $isTrav) {
if ($each && !$isTrav) {
// Detect input type is object or not when never done once
if ($keys == null) {
$keys = array_keys($v);
$isObj = count(array_diff_key($v, array_keys($keys))) > 0;
}
}
$ret = array();
if ($push) {
$cx['scopes'][] = $in;
}
$i = 0;
if ($cx['flags']['spvar']) {
$old_spvar = $cx['sp_vars'];
$cx['sp_vars'] = array_merge(array('root' => $old_spvar['root']), $old_spvar, array('_parent' => $old_spvar));
if (!$isTrav) {
$last = count($keys) - 1;
}
}
$isSparceArray = $isObj && count(array_filter(array_keys($v), 'is_string')) == 0;
foreach ($v as $index => $raw) {
if ($cx['flags']['spvar']) {
$cx['sp_vars']['first'] = $i === 0;
$cx['sp_vars']['last'] = $i == $last;
$cx['sp_vars']['key'] = $index;
$cx['sp_vars']['index'] = $isSparceArray ? $index : $i;
$i++;
}
if (isset($bp[0])) {
$raw = static::m($cx, $raw, array($bp[0] => $raw));
}
if (isset($bp[1])) {
$raw = static::m($cx, $raw, array($bp[1] => $cx['sp_vars']['index']));
}
$ret[] = $cb($cx, $raw);
}
if ($cx['flags']['spvar']) {
if ($isObj) {
unset($cx['sp_vars']['key']);
} else {
unset($cx['sp_vars']['last']);
}
unset($cx['sp_vars']['index']);
unset($cx['sp_vars']['first']);
$cx['sp_vars'] = $old_spvar;
}
if ($push) {
array_pop($cx['scopes']);
}
return join('', $ret);
}
if ($each) {
if ($else !== null) {
$ret = $else($cx, $v);
return $ret;
}
return '';
}
if ($isAry) {
if ($push) {
$cx['scopes'][] = $in;
}
$ret = $cb($cx, $v);
if ($push) {
array_pop($cx['scopes']);
}
return $ret;
}
if ($v === true) {
return $cb($cx, $in);
}
if ($v !== null && $v !== false) {
return $cb($cx, $v);
}
if ($else !== null) {
$ret = $else($cx, $in);
return $ret;
}
return '';
}