' ) { if ( ctype_alnum( substr( $expr, $i + 1, 1 ) ) || substr( $expr, $i + 1, 1 ) === '_' ) { return NULL; } $index_mode = FALSE; } else if ( $chr === '-' && substr( $expr, $i - 1, 1 ) === '<' ) { } else { return NULL; } ++$i; continue; } else if ( $filter_mode ) { # check for the index filter e.g. alpha@<3> if ( $chr === '<' ) { if ( substr( $expr, $i - 1, 1 ) === $filter ) { $index_mode = TRUE; ++$i; continue; } else { return NULL; } # check for filter with argument list e.g. alpha@beta( $, 3, 'aaa') } else if ( $chr === '(' ) { ++$i; if ( tti_iii_do_args( $expr, $i, $length ) === FALSE ) { return NULL; } continue; } } if ( ctype_alnum( $chr ) || $chr === '_' || $chr === $filter || $chr === '.' ) { if ( $chr === $filter ) { $filter_mode = TRUE; } ++$i; continue; } else { if ( !is_scalar( $operand = tti_iii_get_custom_field( substr( $expr, $i0, $i - $i0 ) ) ) ) { error_log( 'tti_iii_eval_product()[1]:return NULL' ); return NULL; } if ( is_numeric( $operand ) ) { $operand = ( integer ) $operand; } if ( $product === NULL ) { $product = $operand; } else if ( is_integer( $product ) && is_integer( $operand ) ) { if ( $operator === '*' ) { $product *= $operand; } else if ( $operator === '/' ) { $product = ( integer ) ( $product / $operand ); } else { $product %= $operand; } } else { error_log( 'tti_iii_eval_product()[2]:return NULL' ); return NULL; } $product_mode = FALSE; $variable_mode = FALSE; $filter_mode = FALSE; $operator = NULL; $i0 = -1; continue; } } else if ( ctype_digit( $chr ) ) { if ( $product_mode === FALSE ) { return NULL; } $integer_mode = TRUE; $i0 = $i; ++$i; continue; } else if ( $chr === '\'' || $chr === '"' ) { if ( $product_mode === FALSE ) { return NULL; } $quote = $chr; $chr0 = $chr; ++$i; $i0 = $i; $string_mode = TRUE; continue; } else if ( ctype_alpha( $chr ) ) { $i0 = $i; $variable_mode = TRUE; ++$i; continue; } if ( ctype_space( $chr ) ) { ++$i; continue; } if ( $chr === '*' || $chr === '/' || $chr === '%' ) { if ( is_string( $product ) ) { return NULL; } $product_mode = TRUE; $operator = $chr; ++$i; continue; } if ( $chr === ')' || $chr === '+' || $chr === '-' || $chr === '&' ) { // right parenthesis or operators of lower priority ends the sequence of multiplicands break; } if ( $chr === '(' ) { if ( $product_mode ) { ++$i; if ( ( $operand = tti_iii_eval_concatenation( $expr, $i, $length ) ) && substr_compare( $expr, ')', $i, 1 ) === 0 ) { if ( $product === NULL ) { $product = $operand; } else if ( is_int( $product ) && is_int( $operand ) ) { $product *= $operand; } else { return NULL; } $product_mode = FALSE; ++$i; continue; } } } return NULL; } return $product; } function tti_iii_do_args( $expr, &$i, $length ) { $argument_mode = TRUE; $integer_mode = FALSE; $string_mode = FALSE; $quote = NULL; while ( $i < $length ) { $chr = substr( $expr, $i, 1 ); if ( $integer_mode ) { if ( ctype_digit( $chr ) ) { ++$i; continue; } else { $integer_mode = FALSE; $argument_mode = FALSE; continue; } } else if ( $string_mode ) { if ( $chr === $quote && substr( $expr, $i - 1, 1 ) !== '\\' ) { $quote = NULL; $string_mode = FALSE; $argument_mode = FALSE; } ++$i; continue; } else if ( $argument_mode ) { # expecting integer, quoted string argument or the placeholder $ if ( ctype_digit( $chr ) ) { $integer_mode = TRUE; ++$i; continue; } else if ( $chr === '\'' || $chr === '"' ) { $quote = $chr; $string_mode = TRUE; ++$i; continue; } else if ( $chr === '$' ) { $argument_mode = FALSE; ++$i; continue; } else if ( ctype_space( $chr ) ) { ++$i; continue; } else { return FALSE; } } else { # expecting comma or right parenthesis if ( $chr === ',' ) { $argument_mode = TRUE; ++$i; continue; } else if ( ctype_space( $chr ) ) { ++$i; continue; } else if ( $chr === ')' ) { ++$i; if ( ctype_alnum( substr( $expr, $i, 1 ) ) || substr( $expr, $i, 1 ) === '_' ) { return FALSE; } return TRUE; } else { return FALSE; } } } } # tti_iii_get_custom_field() must be initialized; the initial call must provide the function to call to get the the value of the custom field. # i.e., tti_iii_get_custom_field() is a wrapper for the function provided on the initial call. function tti_iii_get_custom_field( $field ) { static $get_custom_field; if ( empty( $get_custom_field ) ) { $get_custom_field = $field; return TRUE; } return $get_custom_field( $field ); } ?>