eZ publish Enterprise Component: Component, Design ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ :Author: Jan Borsodi :Revision: $Revision$ :Date: $Date$ Design description ================== Explanation of parameter names. $s String input $v Any value $a An array or hash $n A number $index Numeric index $len Numeric length Also *l* and *r* is appended to the names to specify left hand side and right hand side parameters. Left hand side parameters are always considered the source of the operation. String manipulation ``````````````````` - *string* str_arg( $s, $v ) ( QString::arg ):: preg_replace( "/%[0-9]/", $v ); Skipped - *string* str_replace( $sl, $index, $len, $sr ) ( QString::replace ):: substr( $sl, 0, $index ) . $sr . substr( $sl, $index + $len ); - *string* str_remove( $s, $index, $len ) ( QString::remove ):: substr( $s, 0, $index ) . substr( $s, $index + $len ); - *string* str_chop( $s, $len ) ( QString::chop ):: substr( $s, 0, strlen( $s ) - $len ); - *string* str_chop_front( $s, $len ) ( QString::chop ):: substr( $s, $len ); - *string* str_append( $sl, $sr ) ( QString::append ) ?:: $sl . $sr - *string* str_prepend( $sl, $sr ) ( QString::prepend ) ?:: $sr . $sl - *string* str_compare( $sl, $sr ) ( QString::compare ):: strcmp( $sl, $sr ); - *string* str_nat_compare( $sl, $sr ):: strnatcmp( $sl, $sr ); - *string* str_contains( $sl, $sr ) ( QString::compare ):: strpos( $sl, $sr ) !== false - *string* str_len( $s ) ( QString::count ):: strlen( $s ) - *string* str_left( $s, $len ) ( QString::left ):: substr( $s, 0, $len ) - *string* str_starts_with( $sl, $sr ) ( QString::startsWith ):: strpos( $sl, $sr ) === 0 - *string* str_right( $s, $len ) ( QString::right ):: substr( $s, -$len ) - *string* str_ends_with( $sl, $sr ) ( QString::endsWith ):: strrpos( $sl, $sr ) === ( strlen( $sl ) - 1 ) - *string* str_mid( $s, $index, $len ) ( QString::mid ):: substr( $s, $index, $len ) - *string* str_at( $s, $index ) ( QString::at ):: substr( $s, $index, 1 ) - *string* str_fill( $s, $len ) ( QString::fill ):: str_repeat( $s, $len ) - *string* str_index_of( $sl, $sr [, $index ] ) ( QString::indexOf ):: strpos( $sl, $sr [, $index ] ) - *string* str_last_index( $sl, $sr [, $index] ) ( QString::lastIndexOf ):: strrpos( $sl, $sr [, $index ] ) - *string* str_is_empty( $s ) ( QString::isEmpty() ):: strlen( $s ) === 0 - *string* str_pad_left( $s, $len, $fill ) ( QString::leftJustified() ):: str_pad( $s, $len, $fill, STR_PAD_LEFT ) - *string* str_pad_right( $s, $len, $fill ) ( QString::rightJustified() ):: str_pad( $s, $len, $fill, STR_PAD_RIGHT ) - *string* str_number( $num, $decimals, $point, $sep ):: number_format( $num, $decimals, $point, $sep ) - *string* str_trimmed( $s, $chars = false ) ( QString::trimmed ):: trim( $s, $chars ) - *string* str_trimmed_left( $s, $chars = false ):: ltrim( $s, $chars ) - *string* str_trimmed_right( $s, $chars = false ):: rtrim( $s, $chars ) - *string* str_simplified( $s ) ( QString::simplified ):: trim( preg_replace( "/(\n|\t|\r\n|\s)+/", " ", $s ) ) - *array* str_split( $s, $sep, $max = false ) ( QString::split ):: explode( $sep, $s, $max ) - *string* str_join( $s_list, $sep ) ( QStringList::join ):: join( $sList, $sep ) - *string* str_printf( $format [...] ) ( QString::sprintf ):: sprintf( $format [...] ) Skipped - *string* str_chr( $ord1 [, $ord2...] ):: ord( $ord1 ) [ . ord( $ord2 ) ...] Skipped - *string* str_ord( $c ):: chr( $c ) - *string* str_ord_list( $s ):: chr( $s[0] ) [ . chr( $s[1] ) ] Skipped - *string* str_upper( $s ) ( QString::toUpper ):: strtoupper( $s ) - *string* str_lower( $s ) ( QString::toLower ):: strtolower( $s ) - *string* str_capitalize( $s ):: ucfirst( $s ) - *string* str_find_replace( $s, $find, $replace[, $count] ):: str_replace( $find, $replace, $s[, $count] ) - *string* str_reverse( $s ):: strrev( $s ) - *string* str_section( $s, $sep, $start, $end = -1 ) ( QString::section ):: join( array_slice( split( $s, $sep, $end != -1 ? $end, false ), $start, $end ? $end : false ) ) Skipped - *string* str_char_count( $s ):: strlen( $s ) - *string* str_word_count( $s [, $wordsep] ):: str_word_count( $s, 0 [, $wordsep] ) - *string* str_paragraph_count( $s ):: $pos = 0; $count = 0; while ( preg_match( "/\n\n+/", $s, $m, PREG_OFFSET_CAPTURE, $pos ) { ++$count; $pos = $m[0][1] + 1; } - *string* str_sentence_count( $s ):: $pos = 0; $count = 0; while ( preg_match( "/. /", $s, $m, PREG_OFFSET_CAPTURE, $pos ) { ++$count; $pos = $m[0][1] + 1; } Skipped - *string* str_break( $s, $eol = contextaware, $lbreak = contextaware ):: str_replace( context_eol_char( $eol ), context_linebreak_char( $eol ), $s ) Skipped - *string* str_break_chars( $s, $cbreak ):: $sNew = ''; for ( $i = 0; $i < strlen( $s ) - 1; ++$i ) { $sNew .= $s[$i] . $cbreak; } $sNew .= $s[strlen( $s ) - 1]; Skipped - *string* str_wrap( $s, $width, $break, $cut ):: wordwrap( $s, $width, $break, $cut ) Skipped - *string* str_wrap_indent:: $tmp = wordwrap( $s, $width, $break, $cut ) $lines = explode( "\n", $tmp ); $newLines = array(); foreach ( $lines as $line ) { $newLines[] = $prefix . $line . $suffix; } return join( "\n", $newLines ) Skipped - *string* str_block( $s, $prefix, $suffix ) Skipped - *string* str_shorten_right( $s, $max_size ) Skipped - *string* str_shorten_mid( $s, $max_size ) Skipped - *string* str_shorten_left( $s, $max_size ) Skipped - *string* str_crc32( $s ):: crc32( $s ) Skipped - *string* str_md5( $s ):: md5( $s ) Skipped - *string* str_sha1( $s ):: sha1( $s ) Skipped - *string* str_rot13( $s ):: str_rot13( $s ) Skipped Some of the functions are also available as case insensitive versions, they are: - *string* stri_contains( $sl, $sr ) ( QString::compare ):: stristr( $sl, $sr ) !== false Skipped - *string* stri_starts_with( $sl, $sr ) ( QString::startsWith ):: stripos( strtolower( $sl ), strtolower( $sr ) ) === 0 Skipped - *string* stri_ends_with( $sl, $sr ) ( QString::endsWith ):: strripos( $sl, $sr ) === ( strlen( $sl ) - 1 ) Skipped - *string* stri_index( $sl, $sr [, $from] ) ( QString::indexOf ):: stripos( $sl, $sr [, $from ] ) Skipped - *string* stri_last_index( $sl, $sr [, $from] ) ( QString::lastIndexOf ):: strirpos( $sl, $sr [, $from ] ) Skipped - *string* stri_find_replace( $s, $find, $replace, $count ):: str_ireplace( $s, $replace, $find, $count ) Skipped - *string* stri_compare( $sl, $sr ) ( QString::compare ):: strcasecmp( $sl, $sr ); Skipped - *string* stri_nat_compare( $sl, $sr ):: strnatcasecmp( $sl, $sr ); Skipped - *string* str_base64_encode( $s ) ?:: base64_encode( $s ) - *string* str_base64_decode( $s ) ?:: base64_decode( $s ) Array manipulation `````````````````` - *array* array_count( $a ) ( QList::count ):: count( $a ) - *array* array_contains( $a, $v ) ( QList::contains ):: in_array( $v, $a ) - *array* array_is_empty( $a ) ( QList::isEmpty() ):: count( $a ) === 0 - *array* array_index_of( $a, $v ) ( QList::indexOf() ):: array_search( $v, $a ) - *array* array_index_exists( $a, $index ) ( QMap::find ):: array_key_exists( $index, $a ) - *array* array_left( $a, $len ):: array_slice( $a, 0, $len ) - *array* array_right( $a, $len ):: array_slice( $a, 0, -$len ) - *array* array_mid( $a, $index, $len ) ( QValueList::mid ):: array_slice( $a, $index, $len ) - *array* array_insert( $a, $index, $v1 [, $v2 ...] ) ( QList::insert() ):: array_slice( $a, 0, $index ) + array( $v1 [, $v2 ...] ) + array_slice( $a, $index + value count ) - *array* array_append( $a, $v1 [, $v2 ...] ) ( QList::append() ):: - *array* array_prepend( $a, $v1 [, $v2 ...] ) ( QList::prepend ):: - *array* array_merge( $a1, $a2 [, $a3 ..] ) ( QList::+ ):: array_merge( $a1, $a2 [, $a3 ...] ) - *array* array_remove( $a, $index, $len = 1 ) ( QList::remove ):: array_merge( array_slice( $a, 0, $index ), array_slice( $a, $index + $len) ) - *array* array_remove_first( $a, $len = 1 ) ( QList::removeFirst() ):: array_slice( $a, $len ) - *array* array_remove_last( $a, $len = 1 ) ( QList::removeLast() ):: array_slice( $a, 0, -$len) - *array* array_first( $a ) ( QList::first ):: count( $a ) > 0 ? $a[0] : false - *array* array_last( $a ) ( QList::last ):: count( $a ) > 0 ? $a[count( $a ) - 1] : false - *array* array_replace( $a, $index, $len = 1, $v1 [, $v2 ...] ) ( QList::replace ):: array_slice( $a, 0, $index ) + array( $v1 [, $v2 ...] ) + array_slice( $a, $index + $len ) - *array* array_swap( $a, $index1, $index2 ) ( QList::swap ) ?:: $tmp1 = $a[$index1]; $a[$index1] = $a[$index2]; $a[$index2] = $tmp1; unset( $tmp1 ); - *array* array_at( $a, $index ) ( QList::at ):: $a[$index] Skipped, $a cannot be an array definition. A function will make it slow. - *array* array_reverse( $a ):: array_reverse( $a ) - *array* array_diff( $a1, $a2 [, $a3 ...] ):: array_diff( $a1, $a2 [, $a3 ...] ) - *array* array_insersect( $a1, $a2 [, $a3 ...] ):: array_intersect( $a1, $a2 [, $a3 ...] ) - *array* array_pad( [$a = array(),] $len, $fill ):: array_pad( $a, $len, $fill ) - *array* array_unique( $a ):: array_unique( $a ) - *array* array_find( $a, $v ):: array_search( $v, $a ) - *array* array_find_replace( $a, $v, $vNew ):: $key = array_search( $v, $a ); if ( $key ) $a[$key] = $vNew; - *array* array_fill_range( $low, $high [, $step] ):: array_range( $low, $high [, $step] ) - *array* array_sum( $a ):: array_sum( $a ) - *array* array_extract_by_properties( $a, $pList ):: array_sum( array_extract_by_properties( $order.items, array( 'price' ) ) ) becomes foreach ( $order->items as $item ) { $list[] = $item->price; } array_sum( $list ) unset( $list ) - *array* array_extract_by_keys( $a, $kList ):: array_sum( array_extract_by_keys( $order.items, array( 'price' ) ) ) becomes foreach ( $order->items as $item ) { $list[] = $item['price']; } array_sum( $list ) unset( $list ) Working with associative arrays have some specialized functions - *array* hash_diff( $a1, $a2 [, $a3 ...] ):: array_diff_assoc( $a1, $a2 [, $a3 ...] ) - *array* hash_diff_key( $a1, $a2 [, $a3 ...] ):: array_diff_key( $a1, $a2 [, $a3 ...] ) - *array* hash_intersect( $a1, $a2 [, $a3 ...] ):: array_intersect_assoc( $a1, $a2 [, $a3 ...] ) - *array* hash_intersect_key( $a1, $a2 [, $a3 ...] ):: array_intersect( $a1, $a2 [, $a3 ...] ) - *array* hash_keys( $a ) ( QMap::keys ):: array_keys( $a ) - *array* hash_values( $a ):: array_values( $a ) - *array* hash_flip( $a ):: array_flip( $a ) Creating arrays can be done with: - *array* array_fill( $v, $len ) ( QVector::fill ):: array_fill( 0, $len, $v ) Skipped, can be done with array_pad. - *array* array_repeat( $asrc, $len ) ( QVector::fill ):: $aout = array(); for ( $i = 0; $i < $len; ++$i ) { $aout += $a; } Sorting of arrays is also possible, this will return the sorted array instead of manipulating the input expression. - *array* array_sort( $a ):: $tmpa = $a; sort( $a ); return $tmpa; - *array* array_sort_reverse( $a ):: $tmpa = $a; rsort( $a ); return $tmpa; - *array* hash_sort( $a ):: $tmpa = $a; asort( $a ); return $tmpa; - *array* hash_sort_reverse( $a ):: $tmpa = $a; arsort( $a ); return $tmpa; - *array* hash_sort_keys( $a ):: $tmpa = $a; ksort( $a ); return $tmpa; - *array* hash_sort_keys_reverse( $a ):: $tmpa = $a; krsort( $a ); return $tmpa; Note: The user defined sorting is delibaretely not supported. Regular expression `````````````````` - *bool* preg_has_match( $s, $reg ):: preg_match( $reg, $s ) - *array* preg_match( $s, $reg, $flags = false [, $offset] ):: preg_match( $reg, $s, $matches, $flags [, $offset] ) return $matches; The last two parameters are skipped for now. - *string* preg_replace( $s, $reg, $replace [, $limit] ):: preg_replace( $reg, $replace, $s [, $limit] ) - *string* preg_quote( $s [, $delim] ):: preg_quote( $s [, $delim] ) - *array* preg_split( $reg, $s [, $limit [, $flags] ] ):: preg_split( $reg, $s [, $limit [, $flags] ] ) - *array* preg_grep( $reg, $a [, $flags] ):: preg_grep( $reg, $a [, $flags] ) Web manipulation ```````````````` - url_encode( $url ):: urlencode( $url ) - url_decode( $url ):: urldecode( $url ) - url_parameters_build( $params [, $prefix] ):: http_build_query( $params [, $prefix] ) - *string* url_build( $data (from url_parse) ):: $url = ''; if ( $data['scheme'] && $data['host'] ) { $url .= $data['scheme'] . '://'; if ( $data['user'] ) { $url .= $data['user']; if ( $data['pass'] ) $url .= $data['pass']; $url .= '@'; } $url .= $data['host']; if ( $data['port'] ) $url .= ':' . $data['port']; } $url .= $data['path']; if ( $data['query'] ) $url .= '?' . http_build_query( $data['query'] if ( $data['fragment'] ) $url .= '#' . $data['fragment']; - *hash* url_parse( $url ):: parse_url( $url ) Handling things like ezurl, ezroot and ezimage is still undecided. Variables and types ``````````````````` All functions which deals with null will not be included, it does not make sense to handle this in the template language. - *bool* is_empty( $v ):: empty( $v ) - *bool* is_not_empty( $v ):: !empty( $v ) Might not be needed, using !is_empty should do it. Skipped - *bool* is_array( $v ):: is_array( $v ) - *bool* is_bool( $v ):: is_bool( $v ) - *bool* is_float( $v ):: is_float( $v ) - *bool* is_int( $v ):: is_int( $v ) - *bool* is_numeric( $v ):: is_numeric( $v ) - *bool* is_object( $v ):: is_object( $v ) ? - *bool* is_class( $v, $class ):: getclass( $v ) == $class - *bool* is_scalar( $v ):: is_scalar( $v ) - *bool* is_string( $v ):: is_string( $v ) - *bool* is_set( $v ):: is_set( $v ) - *bool* is_unset( $v ):: !is_set( $v ) Skipped - *string* get_type( $v ):: gettype( $v ) Note: Use debug_dump instead? Skipped - *string* get_class( $v ):: getclass( $v ) Casting to a specific type is done with: - *string* string( $v ):: (string)$v - *int* int( $v ):: (int)$v - *float* float( $v ):: (float)$v - *mixed* get_constant( $const ):: // if ( defined( $const ) ) return constant( $const ); const( $const); - *bool* is_constant( $const ):: return defined( $const ) Arithmetics ``````````` All functions are prefixed with math\_. - max( $v1 , $v2 [, ...] ):: max( $v1 , $v2 [, ...] ) - min( $v1 , $v2 [, ...] ):: min( $v1 , $v2 [, ...] ) - abs( $v ):: abs( $v ) - ceil( $v ):: ceil( $v ) - floor( $v ):: floor( $v ) - round( $v ):: round( $v ) - sqrt( $v ):: sqrt( $v ) - exp( $arg ):: exp( $arg ) - pow( $base, $exp ):: pow( $base, $exp ) - log( $arg, $base ):: log( $arg, $base ) - log10( $arg ):: log10( $arg ) - float_mod( $v ):: fmod( $v ) - rand( $min, $max ):: mt_rand( $min, $max ) - pi():: pi() - is_finite( $v ):: is_finite( $v ) - is_infinite( $v ):: is_infinite( $v ) - is_nan( $v ):: is_nan( $v ) Implemented, although a bit useless. Devision by zero is not possible to test, and this function can mainly be used by Trigonometry functions. Which are not implemented at the time. - bin_to_dec( $s ):: bindec( $s ) - hex_to_dec( $s ):: hexdec( $s ) - oct_to_dec( $s ):: octdec( $s ) - dec_to_bin( $v ):: decbin( $v ) - dec_to_hex( $v ):: dechex( $v ) - dec_to_oct( $v ):: decoct( $v ) - dec_to_roman( $v ):: custom code - format_si( $v, $unit [, $prefix ] ):: custom code Date ```` - date_format_timestamp( $format [, $timestamp] ):: date( $format, $timestamp ) - date_current_timestamp():: time() Trigonometry ```````````` Will we support this? Boolean logic ````````````` Boolean is handled using builtins and operators. Control flow ```````````` .. Note: These entries are only a suggestion. Control flow allows for quick choices of one expression or the other and can be nested as many times as needed. - mixed eval_or( expr1 [, expr2 ...] ) Evaluates one expression at a time until one has a *"true"* value, in which case that value is returned and the rest is ignored. If all values are *"false"* it returns *false*. Equivalent PHP code:: $c1 = eval( $expr1 ) if ( $c1 ) return $c1; $c2 = eval( $expr2 ) if ( $c2 ) return $c2; ... return false - mixed eval_and( expr1 [, expr2 ...] ) Evaluates one expression at a time until one has a *"false"* value, in which case that value is returned and the rest is ignored. If all values are *"true"* it returns *true*. Equivalent PHP code:: $c1 = eval( $expr1 ) if ( !$c1 ) return $c1; $c2 = eval( $expr2 ) if ( !$2 ) return $c2; ... return true - mixed eval_first_set( expr1 [, expr2 ...] ) Examines one expression at a time until all elements in the expression exists, in which case it evaluates the expression and returns the value. Equivalent PHP code:: if ( is_set( $expr1 ) ) { return eval( $expr1 ) } if ( is_set( $expr2 ) ) { return eval( $expr2 ) } ... return false; - mixed eval_index( $n, expr1 [, expr2 ...] ) Uses the first parameter as the lookup value for the following expressions, that means if 0 is passed it will find the first (0th) expression, evaluate it and return the value. Equivalent PHP code:: if ( $n == 0 ) eval( expr1 ) else if ( $n == 1 ) eval( $expr2 ) ... - mixed eval_if( $c, expr1, expr2 ):: $c ? return eval( $expr1 ) : return eval( $expr2 ) - mixed eval_cond( $c1 => expr1 [, $c2 => expr2 ] [, def_expr ] ):: if ( $c1 ) return eval( $expr1 ); else if ( $c2 ) return eval( $expr2 ); else return eval( $def_expr ); - string eval_template( $tpl, $outfile ) Evaluates the references template file $tpl and stores the result in the text file $outfile. The full path to the file is returned which can be used in the template output. If the output file already exists it will not execute the template file again but reuse the file. An example:: @import {eval_template( "design.css.tpl", "design.css" )} Debugging ````````` - debug_dump( $v ) -> use reflection to figure out properties etc. (Replaces attribute operator) Should display the structure of the value:: if ( is_object( $v ) ) // dump properties and their values else var_export( $v, true ); .. Local Variables: mode: rst fill-column: 79 End: vim: et syn=rst tw=79