diff --git a/lib/RainTPL.php b/lib/RainTPL.php deleted file mode 100644 index dc09054e..00000000 --- a/lib/RainTPL.php +++ /dev/null @@ -1,1164 +0,0 @@ - - * - * True: php tags are enabled into the template - * False: php tags are disabled into the template and rendered as html - * - * @var bool - */ - static $php_enabled = false; - - - /** - * Debug mode flag - * - * True: debug mode is used, syntax errors are displayed directly in template. Execution of script is not terminated. - * False: exception is thrown on found error. - * - * @var bool - */ - static $debug = false; - - // ------------------------- - - - // ------------------------- - // RAINTPL VARIABLES - // ------------------------- - - /** - * Is the array where RainTPL keep the variables assigned - * - * @var array - */ - public $var = array(); - - /** - * variables to keep the template directories and info - * - * @var array - */ - protected $tpl = array(); // - - /** - * static cache enabled / disabled - * - * @var bool - */ - protected $cache = false; - - /** - * identify only one cache - * - * @var string - */ - protected $cache_id = ''; - - /** - * takes all the config to create the md5 of the file - * - * @var array the file - */ - protected static $config_name_sum = array(); - - // ------------------------- - - - - /** - * default cache expire time = hour - * - * @const int - */ - const CACHE_EXPIRE_TIME = 3600; - - - - /** - * Assign variable - * eg. $t->assign('name','mickey'); - * - * @access public - * @param mixed $variable_name Name of template variable or associative array name/value - * @param mixed $value value assigned to this variable. Not set if variable_name is an associative array - */ - public function assign( $variable, $value = null ){ - if( is_array( $variable ) ) - $this->var += $variable; - else - $this->var[ $variable ] = $value; - } - - - - /** - * Draw the template - * eg. $html = $tpl->draw( 'demo', TRUE ); // return template in string - * or $tpl->draw( $tpl_name ); // echo the template - * - * @access public - * @param string $tpl_name template to load - * @param boolean $return_string true=return a string, false=echo the template - * @return string - */ - public function draw( $tpl_name, $return_string = false ){ - - try { - // compile the template if necessary and set the template filepath - $this->check_template( $tpl_name ); - } catch (RainTpl_Exception $e) { - $output = $this->printDebug($e); - die($output); - } - - // Cache is off and, return_string is false - // Rain just echo the template - - if( !$this->cache && !$return_string ){ - extract( $this->var ); - include $this->tpl['compiled_filename']; - unset( $this->tpl ); - } - - - // cache or return_string are enabled - // rain get the output buffer to save the output in the cache or to return it as string - - else{ - - //---------------------- - // get the output buffer - //---------------------- - ob_start(); - extract( $this->var ); - include $this->tpl['compiled_filename']; - $raintpl_contents = ob_get_clean(); - //---------------------- - - - // save the output in the cache - if( $this->cache ) - file_put_contents( $this->tpl['cache_filename'], "" . $raintpl_contents ); - - // free memory - unset( $this->tpl ); - - // return or print the template - if( $return_string ) return $raintpl_contents; else echo $raintpl_contents; - - } - - } - - - - /** - * If exists a valid cache for this template it returns the cache - * - * @access public - * @param string $tpl_name Name of template (set the same of draw) - * @param int $expiration_time Set after how many seconds the cache expire and must be regenerated - * @param string $cache_id Suffix to be used when writing file to cache (optional) - * @return string it return the HTML or null if the cache must be recreated - */ - public function cache( $tpl_name, $expire_time = self::CACHE_EXPIRE_TIME, $cache_id = '' ){ - - // set the cache_id - $this->cache_id = $cache_id; - - if( !$this->check_template( $tpl_name ) && file_exists( $this->tpl['cache_filename'] ) && ( time() - filemtime( $this->tpl['cache_filename'] ) < $expire_time ) ) - return substr( file_get_contents( $this->tpl['cache_filename'] ), 43 ); - else{ - //delete the cache of the selected template - if (file_exists($this->tpl['cache_filename'])) - unlink($this->tpl['cache_filename'] ); - $this->cache = true; - } - } - - - - /** - * Configure the settings of RainTPL - * - * @access public - * @static - * @param array|string $setting array of settings or setting name - * @param mixed $value content to set in the setting (optional) - */ - public static function configure( $setting, $value = null ){ - if( is_array( $setting ) ) - foreach( $setting as $key => $value ) - self::configure( $key, $value ); - else if( property_exists( __CLASS__, $setting ) ){ - self::$$setting = $value; - self::$config_name_sum[ $setting ] = $value; // take trace of all config - } - } - - - - /** - * Check if has to compile the template - * - * @access protected - * @param string $tpl_name template name to check - * @throws RainTpl_NotFoundException - * @return bool return true if the template has changed - */ - protected function check_template( $tpl_name ){ - - if( !isset($this->tpl['checked']) ){ - - $tpl_basename = basename( $tpl_name ); // template basename - $tpl_basedir = strpos($tpl_name,"/") ? dirname($tpl_name) . '/' : null; // template basedirectory - $tpl_dir = PATH . self::$tpl_dir . $tpl_basedir; // template directory - $this->tpl['tpl_filename'] = $tpl_dir . $tpl_basename . '.' . self::$tpl_ext; // template filename - $temp_compiled_filename = PATH . self::$cache_dir . $tpl_basename . "." . md5( $tpl_dir . serialize(self::$config_name_sum)); - $this->tpl['compiled_filename'] = $temp_compiled_filename . '.rtpl.php'; // cache filename - $this->tpl['cache_filename'] = $temp_compiled_filename . '.s_' . $this->cache_id . '.rtpl.php'; // static cache filename - - // if the template doesn't exsist throw an error - if( self::$check_template_update && !file_exists( $this->tpl['tpl_filename'] ) ){ - $e = new RainTpl_NotFoundException( 'Template '. $tpl_basename .' not found!' ); - throw $e->setTemplateFile($this->tpl['tpl_filename']); - } - - // file doesn't exsist, or the template was updated, Rain will compile the template - if( !file_exists( $this->tpl['compiled_filename'] ) || ( self::$check_template_update && filemtime($this->tpl['compiled_filename']) < filemtime( $this->tpl['tpl_filename'] ) ) ){ - $this->compileFile( $tpl_basedir, $this->tpl['tpl_filename'], PATH . self::$cache_dir, $this->tpl['compiled_filename'] ); - return true; - } - $this->tpl['checked'] = true; - } - } - - - - /** - * execute stripslaches() on the xml block. Invoqued by preg_replace_callback function below - * - * @access protected - * @param string $capture - * @return string - */ - protected function xml_reSubstitution($capture) { - return "'; ?>"; - } - - - - /** - * Compile and write the compiled template file - * - * @access protected - * @param string $tpl_basedir - * @param string $tpl_filename - * @param string $cache_dir - * @param string $compiled_filename - * @throws RainTpl_Exception - * @return void - */ - protected function compileFile( $tpl_basedir, $tpl_filename, $cache_dir, $compiled_filename ){ - - //read template file - $this->tpl['source'] = $template_code = file_get_contents( $tpl_filename ); - - //xml substitution - $template_code = preg_replace( "/<\?xml(.*?)\?>/s", "##XML\\1XML##", $template_code ); - - //disable php tag - if( !self::$php_enabled ) - $template_code = str_replace( array(""), array("<?","?>"), $template_code ); - - //xml re-substitution - $template_code = preg_replace_callback ( "/##XML(.*?)XML##/s", array($this, 'xml_reSubstitution'), $template_code ); - - //compile template - $template_compiled = "" . $this->compileTemplate( $template_code, $tpl_basedir ); - - - // fix the php-eating-newline-after-closing-tag-problem - $template_compiled = str_replace( "?>\n", "?>\n\n", $template_compiled ); - - // create directories - if( !is_dir( $cache_dir ) ) - mkdir( $cache_dir, 0755, true ); - - if( !is_writable( $cache_dir ) ) - throw new RainTpl_Exception ('Cache directory ' . $cache_dir . ' doesn\'t have write permission. Set write permission or set RAINTPL_CHECK_TEMPLATE_UPDATE to false. More details on http://www.raintpl.com/Documentation/Documentation-for-PHP-developers/Configuration/'); - - //write compiled file - file_put_contents( $compiled_filename, $template_compiled ); - } - - - - /** - * Compile template - * - * @access protected - * @param string $template_code - * @param string $tpl_basedir - * @return string - */ - protected function compileTemplate( $template_code, $tpl_basedir ){ - - //tag list - $tag_regexp = array( 'loop' => '(\{loop(?: name){0,1}="\${0,1}[^"]*"\})', - 'loop_close' => '(\{\/loop\})', - 'if' => '(\{if(?: condition){0,1}="[^"]*"\})', - 'elseif' => '(\{elseif(?: condition){0,1}="[^"]*"\})', - 'else' => '(\{else\})', - 'if_close' => '(\{\/if\})', - 'function' => '(\{function="[^"]*"\})', - 'noparse' => '(\{noparse\})', - 'noparse_close'=> '(\{\/noparse\})', - 'ignore' => '(\{ignore\}|\{\*)', - 'ignore_close' => '(\{\/ignore\}|\*\})', - 'include' => '(\{include="[^"]*"(?: cache="[^"]*")?\})', - 'template_info'=> '(\{\$template_info\})', - 'function' => '(\{function="(\w*?)(?:.*?)"\})' - ); - - $tag_regexp = "/" . join( "|", $tag_regexp ) . "/"; - - //split the code with the tags regexp - $template_code = preg_split ( $tag_regexp, $template_code, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY ); - - //path replace (src of img, background and href of link) - $template_code = $this->path_replace( $template_code, $tpl_basedir ); - - //compile the code - $compiled_code = $this->compileCode( $template_code ); - - //return the compiled code - return $compiled_code; - - } - - - - /** - * Compile the code - * - * @access protected - * @param string $parsed_code - * @throws RainTpl_SyntaxException - * @return string - */ - protected function compileCode( $parsed_code ){ - - //variables initialization - $compiled_code = $open_if = $comment_is_open = $ignore_is_open = null; - $loop_level = 0; - - //read all parsed code - while( $html = array_shift( $parsed_code ) ){ - - //close ignore tag - if( !$comment_is_open && ( strpos( $html, '{/ignore}' ) !== FALSE || strpos( $html, '*}' ) !== FALSE ) ) - $ignore_is_open = false; - - //code between tag ignore id deleted - elseif( $ignore_is_open ){ - //ignore the code - } - - //close no parse tag - elseif( strpos( $html, '{/noparse}' ) !== FALSE ) - $comment_is_open = false; - - //code between tag noparse is not compiled - elseif( $comment_is_open ) - $compiled_code .= $html; - - //ignore - elseif( strpos( $html, '{ignore}' ) !== FALSE || strpos( $html, '{*' ) !== FALSE ) - $ignore_is_open = true; - - //noparse - elseif( strpos( $html, '{noparse}' ) !== FALSE ) - $comment_is_open = true; - - //include tag - elseif( preg_match( '/\{include="([^"]*)"(?: cache="([^"]*)"){0,1}\}/', $html, $code ) ){ - - //variables substitution - $include_var = $this->var_replace( $code[ 1 ], $left_delimiter = null, $right_delimiter = null, $php_left_delimiter = '".' , $php_right_delimiter = '."', $loop_level ); - - // if the cache is active - if( isset($code[ 2 ]) ){ - - //dynamic include - $compiled_code .= 'cache( $template = basename("'.$include_var.'") ) )' . - ' echo $cache;' . - 'else{' . - ' $tpl_dir_temp = self::$tpl_dir;' . - ' $tpl->assign( $this->var );' . - ( !$loop_level ? null : '$tpl->assign( "key", $key'.$loop_level.' ); $tpl->assign( "value", $value'.$loop_level.' );' ). - ' $tpl->draw( dirname("'.$include_var.'") . ( substr("'.$include_var.'",-1,1) != "/" ? "/" : "" ) . basename("'.$include_var.'") );'. - '} ?>'; - } - else{ - - //dynamic include - $compiled_code .= 'assign( $this->var );' . - ( !$loop_level ? null : '$tpl->assign( "key", $key'.$loop_level.' ); $tpl->assign( "value", $value'.$loop_level.' );' ). - '$tpl->draw( dirname("'.$include_var.'") . ( substr("'.$include_var.'",-1,1) != "/" ? "/" : "" ) . basename("'.$include_var.'") );'. - '?>'; - - - } - - } - - //loop - elseif( preg_match( '/\{loop(?: name){0,1}="\${0,1}([^"]*)"\}/', $html, $code ) ){ - - //increase the loop counter - $loop_level++; - - //replace the variable in the loop - $var = $this->var_replace( '$' . $code[ 1 ], $tag_left_delimiter=null, $tag_right_delimiter=null, $php_left_delimiter=null, $php_right_delimiter=null, $loop_level-1 ); - - //loop variables - $counter = "\$counter$loop_level"; // count iteration - $key = "\$key$loop_level"; // key - $value = "\$value$loop_level"; // value - - //loop code - $compiled_code .= " $value ){ $counter++; ?>"; - - } - - //close loop tag - elseif( strpos( $html, '{/loop}' ) !== FALSE ) { - - //iterator - $counter = "\$counter$loop_level"; - - //decrease the loop counter - $loop_level--; - - //close loop code - $compiled_code .= ""; - - } - - //if - elseif( preg_match( '/\{if(?: condition){0,1}="([^"]*)"\}/', $html, $code ) ){ - - //increase open if counter (for intendation) - $open_if++; - - //tag - $tag = $code[ 0 ]; - - //condition attribute - $condition = $code[ 1 ]; - - // check if there's any function disabled by black_list - $this->function_check( $tag ); - - //variable substitution into condition (no delimiter into the condition) - $parsed_condition = $this->var_replace( $condition, $tag_left_delimiter = null, $tag_right_delimiter = null, $php_left_delimiter = null, $php_right_delimiter = null, $loop_level ); - - //if code - $compiled_code .= ""; - - } - - //elseif - elseif( preg_match( '/\{elseif(?: condition){0,1}="([^"]*)"\}/', $html, $code ) ){ - - //tag - $tag = $code[ 0 ]; - - //condition attribute - $condition = $code[ 1 ]; - - //variable substitution into condition (no delimiter into the condition) - $parsed_condition = $this->var_replace( $condition, $tag_left_delimiter = null, $tag_right_delimiter = null, $php_left_delimiter = null, $php_right_delimiter = null, $loop_level ); - - //elseif code - $compiled_code .= ""; - } - - //else - elseif( strpos( $html, '{else}' ) !== FALSE ) { - - //else code - $compiled_code .= ''; - - } - - //close if tag - elseif( strpos( $html, '{/if}' ) !== FALSE ) { - - //decrease if counter - $open_if--; - - // close if code - $compiled_code .= ''; - - } - - //function - elseif( preg_match( '/\{function="(\w*)(.*?)"\}/', $html, $code ) ){ - - //tag - $tag = $code[ 0 ]; - - //function - $function = $code[ 1 ]; - - // check if there's any function disabled by black_list - $this->function_check( $tag ); - - if( empty( $code[ 2 ] ) ) - $parsed_function = $function . "()"; - else - // parse the function - $parsed_function = $function . $this->var_replace( $code[ 2 ], $tag_left_delimiter = null, $tag_right_delimiter = null, $php_left_delimiter = null, $php_right_delimiter = null, $loop_level ); - - //if code - $compiled_code .= ""; - } - - // show all vars - elseif ( strpos( $html, '{$template_info}' ) !== FALSE ) { - - //tag - $tag = '{$template_info}'; - - //if code - $compiled_code .= '"; print_r( $this->var ); echo ""; ?>'; - } - - - //all html code - else{ - - //variables substitution (es. {$title}) - $html = $this->var_replace( $html, $left_delimiter = '\{', $right_delimiter = '\}', $php_left_delimiter = '', $loop_level, $echo = true ); - //const substitution (es. {#CONST#}) - $html = $this->const_replace( $html, $left_delimiter = '\{', $right_delimiter = '\}', $php_left_delimiter = '', $loop_level, $echo = true ); - //functions substitution (es. {"string"|functions}) - $compiled_code .= $this->func_replace( $html, $left_delimiter = '\{', $right_delimiter = '\}', $php_left_delimiter = '', $loop_level, $echo = true ); - } - } - - if( $open_if > 0 ) { - $e = new RainTpl_SyntaxException('Error! You need to close an {if} tag in ' . $this->tpl['tpl_filename'] . ' template'); - throw $e->setTemplateFile($this->tpl['tpl_filename']); - } - return $compiled_code; - } - - - - /** - * Reduce a path - * - * eg. www/library/../filepath//file => www/filepath/file - * - * @param string $path - * @return string - */ - protected function reduce_path( $path ){ - $path = str_replace( "://", "@not_replace@", $path ); - $path = str_replace( "//", "/", $path ); - $path = str_replace( "@not_replace@", "://", $path ); - return preg_replace('/\w+\/\.\.\//', '', $path ); - } - - - - /** - * replace the path of image src, link href and a href - * - * url => template_dir/url - * url# => url - * http://url => http://url - * - * @access protected - * @param string $html - * @param string $tpl_basedir - * @return string html substitution - */ - protected function path_replace( $html, $tpl_basedir ){ - - if( self::$path_replace ){ - - $tpl_dir = self::$base_url . PATH . self::$tpl_dir . $tpl_basedir; - - // reduce the path - $path = $this->reduce_path($tpl_dir); - - $exp = $sub = array(); - - if( in_array( "img", self::$path_replace_list ) ){ - $exp = array( '/function_check( $tag ); - - $extra_var = $this->var_replace( $extra_var, null, null, null, null, $loop_level ); - - - // check if there's an operator = in the variable tags, if there's this is an initialization so it will not output any value - $is_init_variable = preg_match( "/^(\s*?)\=[^=](.*?)$/", $extra_var ); - - //function associate to variable - $function_var = ( $extra_var and $extra_var[0] == '|') ? substr( $extra_var, 1 ) : null; - - //variable path split array (ex. $news.title o $news[title]) or object (ex. $news->title) - $temp = preg_split( "/\.|\[|\-\>/", $var ); - - //variable name - $var_name = $temp[ 0 ]; - - //variable path - $variable_path = substr( $var, strlen( $var_name ) ); - - //parentesis transform [ e ] in [" e in "] - $variable_path = str_replace( '[', '["', $variable_path ); - $variable_path = str_replace( ']', '"]', $variable_path ); - - //transform .$variable in ["$variable"] - $variable_path = preg_replace('/\.\$(\w+)/', '["$\\1"]', $variable_path ); - - //transform [variable] in ["variable"] - $variable_path = preg_replace('/\.(\w+)/', '["\\1"]', $variable_path ); - - //if there's a function - if( $function_var ){ - - // check if there's a function or a static method and separate, function by parameters - $function_var = str_replace("::", "@double_dot@", $function_var ); - - // get the position of the first : - if( $dot_position = strpos( $function_var, ":" ) ){ - - // get the function and the parameters - $function = substr( $function_var, 0, $dot_position ); - $params = substr( $function_var, $dot_position+1 ); - - } - else{ - - //get the function - $function = str_replace( "@double_dot@", "::", $function_var ); - $params = null; - - } - - // replace back the @double_dot@ with :: - $function = str_replace( "@double_dot@", "::", $function ); - $params = str_replace( "@double_dot@", "::", $params ); - - - } - else - $function = $params = null; - - $php_var = $var_name . $variable_path; - - // compile the variable for php - if( isset( $function ) ){ - if( $php_var ) - $php_var = $php_left_delimiter . ( !$is_init_variable && $echo ? 'echo ' : null ) . ( $params ? "( $function( $php_var, $params ) )" : "$function( $php_var )" ) . $php_right_delimiter; - else - $php_var = $php_left_delimiter . ( !$is_init_variable && $echo ? 'echo ' : null ) . ( $params ? "( $function( $params ) )" : "$function()" ) . $php_right_delimiter; - } - else - $php_var = $php_left_delimiter . ( !$is_init_variable && $echo ? 'echo ' : null ) . $php_var . $extra_var . $php_right_delimiter; - - $html = str_replace( $tag, $php_var, $html ); - - } - - return $html; - - } - - - - /** - * replace variables - * - * @access public - * @param string $html - * @param string $tag_left_delimiter - * @param string $tag_right_delimiter - * @param string $php_left_delimiter (optional) - * @param string $php_right_delimiter (optional) - * @param string $loop_level (optional) - * @param string $echo (optional) - * @return string - */ - public function var_replace( $html, $tag_left_delimiter, $tag_right_delimiter, $php_left_delimiter = null, $php_right_delimiter = null, $loop_level = null, $echo = null ){ - - //all variables - if( preg_match_all( '/' . $tag_left_delimiter . '\$(\w+(?:\.\${0,1}[A-Za-z0-9_]+)*(?:(?:\[\${0,1}[A-Za-z0-9_]+\])|(?:\-\>\${0,1}[A-Za-z0-9_]+))*)(.*?)' . $tag_right_delimiter . '/', $html, $matches ) ){ - - for( $parsed=array(), $i=0, $n=count($matches[0]); $i<$n; $i++ ) - $parsed[$matches[0][$i]] = array('var'=>$matches[1][$i],'extra_var'=>$matches[2][$i]); - - foreach( $parsed as $tag => $array ){ - - //variable name ex: news.title - $var = $array['var']; - - //function and parameters associate to the variable ex: substr:0,100 - $extra_var = $array['extra_var']; - - // check if there's any function disabled by black_list - $this->function_check( $tag ); - - $extra_var = $this->var_replace( $extra_var, null, null, null, null, $loop_level ); - - // check if there's an operator = in the variable tags, if there's this is an initialization so it will not output any value - $is_init_variable = preg_match( "/^[a-z_A-Z\.\[\](\-\>)]*=[^=]*$/", $extra_var ); - - //function associate to variable - $function_var = ( $extra_var and $extra_var[0] == '|') ? substr( $extra_var, 1 ) : null; - - //variable path split array (ex. $news.title o $news[title]) or object (ex. $news->title) - $temp = preg_split( "/\.|\[|\-\>/", $var ); - - //variable name - $var_name = $temp[ 0 ]; - - //variable path - $variable_path = substr( $var, strlen( $var_name ) ); - - //parentesis transform [ e ] in [" e in "] - $variable_path = str_replace( '[', '["', $variable_path ); - $variable_path = str_replace( ']', '"]', $variable_path ); - - //transform .$variable in ["$variable"] and .variable in ["variable"] - $variable_path = preg_replace('/\.(\${0,1}\w+)/', '["\\1"]', $variable_path ); - - // if is an assignment also assign the variable to $this->var['value'] - if( $is_init_variable ) - $extra_var = "=\$this->var['{$var_name}']{$variable_path}" . $extra_var; - - - - //if there's a function - if( $function_var ){ - - // check if there's a function or a static method and separate, function by parameters - $function_var = str_replace("::", "@double_dot@", $function_var ); - - - // get the position of the first : - if( $dot_position = strpos( $function_var, ":" ) ){ - - // get the function and the parameters - $function = substr( $function_var, 0, $dot_position ); - $params = substr( $function_var, $dot_position+1 ); - - } - else{ - - //get the function - $function = str_replace( "@double_dot@", "::", $function_var ); - $params = null; - - } - - // replace back the @double_dot@ with :: - $function = str_replace( "@double_dot@", "::", $function ); - $params = str_replace( "@double_dot@", "::", $params ); - } - else - $function = $params = null; - - //if it is inside a loop - if( $loop_level ){ - //verify the variable name - if( $var_name == 'key' ) - $php_var = '$key' . $loop_level; - elseif( $var_name == 'value' ) - $php_var = '$value' . $loop_level . $variable_path; - elseif( $var_name == 'counter' ) - $php_var = '$counter' . $loop_level; - else - $php_var = '$' . $var_name . $variable_path; - }else - $php_var = '$' . $var_name . $variable_path; - - // compile the variable for php - if( isset( $function ) ) - $php_var = $php_left_delimiter . ( !$is_init_variable && $echo ? 'echo ' : null ) . ( $params ? "( $function( $php_var, $params ) )" : "$function( $php_var )" ) . $php_right_delimiter; - else - $php_var = $php_left_delimiter . ( !$is_init_variable && $echo ? 'echo ' : null ) . $php_var . $extra_var . $php_right_delimiter; - - $html = str_replace( $tag, $php_var, $html ); - - - } - } - - return $html; - } - - - - /** - * Check if function is in black list (sandbox) - * - * @access protected - * @param string $code - * @throws RainTpl_SyntaxException - * @return void - */ - protected function function_check( $code ){ - - $preg = '#(\W|\s)' . implode( '(\W|\s)|(\W|\s)', self::$black_list ) . '(\W|\s)#'; - - // check if the function is in the black list (or not in white list) - if( count(self::$black_list) && preg_match( $preg, $code, $match ) ){ - - // find the line of the error - $line = 0; - $rows=explode("\n",$this->tpl['source']); - while( !strpos($rows[$line],$code) ) - $line++; - - // stop the execution of the script - $e = new RainTpl_SyntaxException('Unallowed syntax in ' . $this->tpl['tpl_filename'] . ' template'); - throw $e->setTemplateFile($this->tpl['tpl_filename']) - ->setTag($code) - ->setTemplateLine($line); - } - - } - - - - /** - * Prints debug info about exception or passes it further if debug is disabled. - * - * @access protected - * @param RainTpl_Exception $e - * @return string - */ - protected function printDebug(RainTpl_Exception $e){ - if (!self::$debug) { - throw $e; - } - $output = sprintf('

Exception: %s

%s

template: %s

', - get_class($e), - $e->getMessage(), - $e->getTemplateFile() - ); - if ($e instanceof RainTpl_SyntaxException) { - if (null !== $e->getTemplateLine()) { - $output .= '

line: ' . $e->getTemplateLine() . '

'; - } - if (null !== $e->getTag()) { - $output .= '

in tag: ' . htmlspecialchars($e->getTag()) . '

'; - } - if (null !== $e->getTemplateLine() && null !== $e->getTag()) { - $rows=explode("\n", htmlspecialchars($this->tpl['source'])); - $rows[$e->getTemplateLine()] = '' . $rows[$e->getTemplateLine()] . ''; - $output .= '

template code

' . implode('
', $rows) . ''; - } - } - $output .= sprintf('

trace

In %s on line %d

%s
', - $e->getFile(), $e->getLine(), - nl2br(htmlspecialchars($e->getTraceAsString())) - ); - return $output; - } -} - - - -/** - * Basic Rain tpl exception. - */ -class RainTpl_Exception extends Exception{ - /** - * Path of template file with error. - */ - protected $templateFile = ''; - - /** - * Returns path of template file with error. - * - * @return string - */ - public function getTemplateFile() - { - return $this->templateFile; - } - - /** - * Sets path of template file with error. - * - * @param string $templateFile - * @return RainTpl_Exception - */ - public function setTemplateFile($templateFile) - { - $this->templateFile = (string) $templateFile; - return $this; - } -} - - - -/** - * Exception thrown when template file does not exists. - */ -class RainTpl_NotFoundException extends RainTpl_Exception{ -} - -/** - * Exception thrown when syntax error occurs. - */ -class RainTpl_SyntaxException extends RainTpl_Exception{ - /** - * Line in template file where error has occured. - * - * @var int | null - */ - protected $templateLine = null; - - /** - * Tag which caused an error. - * - * @var string | null - */ - protected $tag = null; - - /** - * Returns line in template file where error has occured - * or null if line is not defined. - * - * @return int | null - */ - public function getTemplateLine() - { - return $this->templateLine; - } - - /** - * Sets line in template file where error has occured. - * - * @param int $templateLine - * @return RainTpl_SyntaxException - */ - public function setTemplateLine($templateLine) - { - $this->templateLine = (int) $templateLine; - return $this; - } - - /** - * Returns tag which caused an error. - * - * @return string - */ - public function getTag() - { - return $this->tag; - } - - /** - * Sets tag which caused an error. - * - * @param string $tag - * @return RainTpl_SyntaxException - */ - public function setTag($tag) - { - $this->tag = (string) $tag; - return $this; - } -} - -// -- end diff --git a/lib/privatebin.php b/lib/privatebin.php index baf9864f..aa0f68cb 100644 --- a/lib/privatebin.php +++ b/lib/privatebin.php @@ -423,10 +423,8 @@ class privatebin setcookie('lang', $languageselection); } - $page = new RainTPL; - $page::$path_replace = false; - // we escape it here because ENT_NOQUOTES can't be used in RainTPL templates - $page->assign('CIPHERDATA', htmlspecialchars($this->_data, ENT_NOQUOTES)); + $page = new view; + $page->assign('CIPHERDATA', $this->_data); $page->assign('ERROR', i18n::_($this->_error)); $page->assign('STATUS', i18n::_($this->_status)); $page->assign('VERSION', self::VERSION); diff --git a/lib/view.php b/lib/view.php new file mode 100644 index 00000000..45952006 --- /dev/null +++ b/lib/view.php @@ -0,0 +1,59 @@ +_variables[$name] = $value; + } + + /** + * render a template + * + * @access public + * @param string $template + * @throws Exception + * @return void + */ + public function draw($template) + { + $path = PATH . 'tpl' . DIRECTORY_SEPARATOR . $template . '.php'; + if (!file_exists($path)) + { + throw new Exception('Template ' . $template . ' not found!', 80); + } + extract($this->_variables); + include $path; + } +} diff --git a/tpl/bootstrap-compact.html b/tpl/bootstrap-compact.php similarity index 50% rename from tpl/bootstrap-compact.html rename to tpl/bootstrap-compact.php index eefef691..084971e2 100644 --- a/tpl/bootstrap-compact.html +++ b/tpl/bootstrap-compact.php @@ -5,29 +5,37 @@ - {function="i18n::_('PrivateBin')"} + <?php echo i18n::_('PrivateBin'); ?> - {if="$SYNTAXHIGHLIGHTING"} - {if="strlen($SYNTAXHIGHLIGHTINGTHEME)"} - {/if}{/if} + + + - + - {if="$SYNTAXHIGHLIGHTING"} - {/if}{if="$MARKDOWN"} - {/if} - + + + + - - - - - + + + + + @@ -37,83 +45,102 @@
-
{if="strlen($NOTICE)"} +
{/if} + + {if="$FILEUPLOAD"} + {/if}{if="strlen($STATUS)"} + + {/if} - - - - + + + +
@@ -198,19 +238,19 @@
-

{function="i18n::_('PrivateBin')"} - {function="i18n::_('Because ignorance is bliss')"}

-

{$VERSION}

+

-

+

- {function="i18n::_('PrivateBin is a minimalist, open source online pastebin where the server has zero knowledge of pasted data. Data is encrypted/decrypted in the browser using 256 bits AES. More information on the project page.')"} + in the browser using 256 bits AES. More information on the project page.'); ?>

- + diff --git a/tpl/bootstrap-dark-page.html b/tpl/bootstrap-dark-page.html deleted file mode 100644 index 7e2619aa..00000000 --- a/tpl/bootstrap-dark-page.html +++ /dev/null @@ -1,212 +0,0 @@ - - - - - - - - {function="i18n::_('PrivateBin')"} - - - {if="$SYNTAXHIGHLIGHTING"} - {if="strlen($SYNTAXHIGHLIGHTINGTHEME)"} - {/if}{/if} - - - - - - {if="$SYNTAXHIGHLIGHTING"} - {/if}{if="$MARKDOWN"} - {/if} - - - - - - - - - - - - - -
{if="strlen($NOTICE)"} - {/if} - {if="$FILEUPLOAD"} - {/if}{if="strlen($STATUS)"} - {/if} - - - - - - -
-
-
- - - -

-
-
-
- -
-
-
-

{function="i18n::_('PrivateBin')"} - {function="i18n::_('Because ignorance is bliss')"}

-

{$VERSION}

-

- {function="i18n::_('PrivateBin is a minimalist, open source online pastebin where the server has zero knowledge of pasted data. Data is encrypted/decrypted in the browser using 256 bits AES. More information on the project page.')"} -

-
-
- - - diff --git a/tpl/bootstrap-dark-page.php b/tpl/bootstrap-dark-page.php new file mode 100644 index 00000000..25150082 --- /dev/null +++ b/tpl/bootstrap-dark-page.php @@ -0,0 +1,252 @@ + + + + + + + + <?php echo i18n::_('PrivateBin'); ?> + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+ + + +

+
+
+
+ +
+
+
+

-

+

+

+ in the browser using 256 bits AES. More information on the project page.'); ?> +

+
+
+ + + diff --git a/tpl/bootstrap-dark.html b/tpl/bootstrap-dark.html deleted file mode 100644 index 543446f9..00000000 --- a/tpl/bootstrap-dark.html +++ /dev/null @@ -1,212 +0,0 @@ - - - - - - - - {function="i18n::_('PrivateBin')"} - - - {if="$SYNTAXHIGHLIGHTING"} - {if="strlen($SYNTAXHIGHLIGHTINGTHEME)"} - {/if}{/if} - - - - - - {if="$SYNTAXHIGHLIGHTING"} - {/if}{if="$MARKDOWN"} - {/if} - - - - - - - - - - - - - -
{if="strlen($NOTICE)"} - {/if} - {if="$FILEUPLOAD"} - {/if}{if="strlen($STATUS)"} - {/if} - - - - - - -
-
-
- - - -

-
-
-
- -
-
-
-

{function="i18n::_('PrivateBin')"} - {function="i18n::_('Because ignorance is bliss')"}

-

{$VERSION}

-

- {function="i18n::_('PrivateBin is a minimalist, open source online pastebin where the server has zero knowledge of pasted data. Data is encrypted/decrypted in the browser using 256 bits AES. More information on the project page.')"} -

-
-
- - - diff --git a/tpl/bootstrap-dark.php b/tpl/bootstrap-dark.php new file mode 100644 index 00000000..b3732968 --- /dev/null +++ b/tpl/bootstrap-dark.php @@ -0,0 +1,252 @@ + + + + + + + + <?php echo i18n::_('PrivateBin'); ?> + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+ + + +

+
+
+
+ +
+
+
+

-

+

+

+ in the browser using 256 bits AES. More information on the project page.'); ?> +

+
+
+ + + diff --git a/tpl/bootstrap-page.html b/tpl/bootstrap-page.html deleted file mode 100644 index f2e049a8..00000000 --- a/tpl/bootstrap-page.html +++ /dev/null @@ -1,212 +0,0 @@ - - - - - - - - {function="i18n::_('PrivateBin')"} - - - {if="$SYNTAXHIGHLIGHTING"} - {if="strlen($SYNTAXHIGHLIGHTINGTHEME)"} - {/if}{/if} - - - - - - {if="$SYNTAXHIGHLIGHTING"} - {/if}{if="$MARKDOWN"} - {/if} - - - - - - - - - - - - - -
{if="strlen($NOTICE)"} - {/if} - {if="$FILEUPLOAD"} - {/if}{if="strlen($STATUS)"} - {/if} - - - - - - -
-
-
- - - -

-
-
-
- -
-
-
-

{function="i18n::_('PrivateBin')"} - {function="i18n::_('Because ignorance is bliss')"}

-

{$VERSION}

-

- {function="i18n::_('PrivateBin is a minimalist, open source online pastebin where the server has zero knowledge of pasted data. Data is encrypted/decrypted in the browser using 256 bits AES. More information on the project page.')"} -

-
-
- - - diff --git a/tpl/bootstrap-page.php b/tpl/bootstrap-page.php new file mode 100644 index 00000000..1118076e --- /dev/null +++ b/tpl/bootstrap-page.php @@ -0,0 +1,252 @@ + + + + + + + + <?php echo i18n::_('PrivateBin'); ?> + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+ + + +

+
+
+
+ +
+
+
+

-

+

+

+ in the browser using 256 bits AES. More information on the project page.'); ?> +

+
+
+ + + diff --git a/tpl/bootstrap.html b/tpl/bootstrap.html deleted file mode 100644 index 9072d143..00000000 --- a/tpl/bootstrap.html +++ /dev/null @@ -1,212 +0,0 @@ - - - - - - - - {function="i18n::_('PrivateBin')"} - - - {if="$SYNTAXHIGHLIGHTING"} - {if="strlen($SYNTAXHIGHLIGHTINGTHEME)"} - {/if}{/if} - - - - - - {if="$SYNTAXHIGHLIGHTING"} - {/if}{if="$MARKDOWN"} - {/if} - - - - - - - - - - - - - -
{if="strlen($NOTICE)"} - {/if} - {if="$FILEUPLOAD"} - {/if}{if="strlen($STATUS)"} - {/if} - - - - - - -
-
-
- - - -

-
-
-
- -
-
-
-

{function="i18n::_('PrivateBin')"} - {function="i18n::_('Because ignorance is bliss')"}

-

{$VERSION}

-

- {function="i18n::_('PrivateBin is a minimalist, open source online pastebin where the server has zero knowledge of pasted data. Data is encrypted/decrypted in the browser using 256 bits AES. More information on the project page.')"} -

-
-
- - - diff --git a/tpl/bootstrap.php b/tpl/bootstrap.php new file mode 100644 index 00000000..7d093da2 --- /dev/null +++ b/tpl/bootstrap.php @@ -0,0 +1,252 @@ + + + + + + + + <?php echo i18n::_('PrivateBin'); ?> + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + +
+
+
+ + + +

+
+
+
+ +
+
+
+

-

+

+

+ in the browser using 256 bits AES. More information on the project page.'); ?> +

+
+
+ + + diff --git a/tpl/page.html b/tpl/page.html deleted file mode 100644 index 10fb4efd..00000000 --- a/tpl/page.html +++ /dev/null @@ -1,121 +0,0 @@ - - - - - - {function="i18n::_('PrivateBin')"} - {if="$SYNTAXHIGHLIGHTING"} - {if="strlen($SYNTAXHIGHLIGHTINGTHEME)"} - {/if}{/if} - - - - - {if="$SYNTAXHIGHLIGHTING"} - {/if}{if="$MARKDOWN"} - {/if} - - - - - - - - - - - - -
-
- {function="i18n::_('PrivateBin is a minimalist, open source online pastebin where the server has zero knowledge of pasted data. Data is encrypted/decrypted in the browser using 256 bits AES. More information on the project page.')"}
{if="strlen($NOTICE)"} - {$NOTICE}{/if} -
-

{function="i18n::_('PrivateBin')"}


-

{function="i18n::_('Because ignorance is bliss')"}


-

{$VERSION}

- -
{function="i18n::_('PrivateBin requires a modern browser to work.')"}
-
{function="i18n::_('Still using Internet Explorer? Do yourself a favor, switch to a modern browser:')"} - Firefox, - Opera, - Chrome, - Safari, - Edge... -
-
-
-
-
{$STATUS|htmlspecialchars}
- -
- - {if="$EXPIRECLONE"} - {/if} - - - - {if="$DISCUSSION"} - {/if}{if="$PASSWORD"} - {/if} - {if="strlen($LANGUAGESELECTION)"} -
- -
{/if} -
- {if="$FILEUPLOAD"} - - {/if} - - - - - -
-
-
- -
- - - diff --git a/tpl/page.php b/tpl/page.php new file mode 100644 index 00000000..e7677ce5 --- /dev/null +++ b/tpl/page.php @@ -0,0 +1,157 @@ + + + + + + <?php echo i18n::_('PrivateBin'); ?> + + + + + + + + + + + + + + + + + + + + + + +
+
+ in the browser using 256 bits AES. More information on the project page.'); ?>
+ +
+


+


+

+ +
+
+ Firefox, + Opera, + Chrome, + Safari... +
+
+
+
+
+ +
+ + + + + + + + + + +
+ +
+
+ + + + + + + + +
+
+
+ +
+ + + diff --git a/tst/RainTPL.php b/tst/view.php similarity index 83% rename from tst/RainTPL.php rename to tst/view.php index fe8aa0d6..39c71ca7 100644 --- a/tst/RainTPL.php +++ b/tst/view.php @@ -1,10 +1,18 @@ 'Plain Text', + 'syntaxhighlighting' => 'Source Code', + 'markdown' => 'Markdown', + ); + + private static $formatter_default = 'plaintext'; + private static $expire = array( '5min' => '5 minutes', '1hour' => '1 hour', @@ -20,12 +28,8 @@ class RainTPLTest extends PHPUnit_Framework_TestCase public function setUp() { /* Setup Routine */ - $page = new RainTPL; - $page::configure(array('cache_dir' => 'tmp/')); - $page::$path_replace = false; - - // We escape it here because ENT_NOQUOTES can't be used in RainTPL templates. - $page->assign('CIPHERDATA', htmlspecialchars(helper::getPaste()['data'], ENT_NOQUOTES)); + $page = new view; + $page->assign('CIPHERDATA', helper::getPaste()['data']); $page->assign('ERROR', self::$error); $page->assign('STATUS', self::$status); $page->assign('VERSION', self::$version); @@ -34,6 +38,8 @@ class RainTPLTest extends PHPUnit_Framework_TestCase $page->assign('MARKDOWN', true); $page->assign('SYNTAXHIGHLIGHTING', true); $page->assign('SYNTAXHIGHLIGHTINGTHEME', 'sons-of-obsidian'); + $page->assign('FORMATTER', self::$formatters); + $page->assign('FORMATTERDEFAULT', self::$formatter_default); $page->assign('BURNAFTERREADINGSELECTED', false); $page->assign('PASSWORD', true); $page->assign('FILEUPLOAD', false); @@ -48,16 +54,12 @@ class RainTPLTest extends PHPUnit_Framework_TestCase ob_start(); $page->draw('page'); $this->_content = ob_get_contents(); - // run a second time from cache - $page->cache('page'); - $page->draw('page'); ob_end_clean(); } public function tearDown() { /* Tear Down Routine */ - helper::rmdir(PATH . 'tmp'); } public function testTemplateRendersCorrectly() @@ -98,11 +100,12 @@ class RainTPLTest extends PHPUnit_Framework_TestCase } /** - * @expectedException RainTpl_Exception + * @expectedException Exception + * @expectedExceptionCode 80 */ public function testMissingTemplate() { - $test = new RainTPL; + $test = new view; $test->draw('123456789 does not exist!'); } }