Browse Source

Now with Balanced Parentheses!

it's not regex, its not posix, but it can fly… finally balanced
parentheses to fix all the () issue. it's ugly but it's fast and works
with all kinds of combinations.

it basically just counts open vs. closed and if they are even again it
knows exactly where the condition is and does not cut into html or cut
off too much.
Tobsn 12 years ago
parent
commit
a04f38c262
1 changed files with 36 additions and 3 deletions
  1. 36 3
      laravel/blade.php

+ 36 - 3
laravel/blade.php

@@ -260,9 +260,42 @@ class Blade {
 	 */
 	protected static function compile_structure_openings($value)
 	{
-		$pattern = '/@(if|elseif|foreach|for|while)\s*?(\(.+?\))/';
-
-		return preg_replace($pattern, '<?php $1$2: ?>', $value);
+		preg_replace_callback(
+			'/@(if|elseif|foreach|for|while)(\s*?)(\([^\n\r\t]+\))/',
+			function($matches) use (&$value)
+			{
+				if(count( $matches ) === 4)
+				{
+					$open  = 0;
+					$close = 0;
+					$cut   = 0;
+					$len   = strlen($matches[3]);
+					for($i = 0; $i < $len; $i++)
+					{
+						if($matches[3][$i] === '(' )
+						{
+							$open++;
+						}
+						if($matches[3][$i] === ')' )
+						{
+							$close++;
+						}
+						if($open !== 0 && ($open === $close))
+						{
+							break;
+						}
+					}
+					$condition = substr($matches[3], 0, ($i + 1));
+					$value = str_replace(
+						'@'.$matches[1].$matches[2].$condition,
+						'<?php '.$matches[1].$condition.': ?>',
+						$value
+					);
+				}
+			},
+			$value
+		);
+		return $value;
 	}
 
 	/**