Changeset 1068480
- Timestamp:
- 01/15/2015 10:20:15 AM (11 years ago)
- Location:
- enzymes/trunk
- Files:
-
- 2 edited
-
src/Enzymes3.php (modified) (16 diffs)
-
tests/test-Enzymes3.php (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
enzymes/trunk/src/Enzymes3.php
r1067352 r1068480 32 32 33 33 /** 34 * @var bool 35 */ 36 public $debug_on = false; 37 38 /** 39 * @param mixed $something 40 */ 41 public 42 function debug_print( $something ) 43 { 44 if ( ! $this->debug_on ) { 45 return; 46 } 47 fwrite(STDERR, "\n" . print_r($something, true) . "\n"); 48 } 34 * Current sequence. 35 * 36 * @var string 37 */ 38 protected $current_sequence; 39 40 /** 41 * Current enzyme. 42 * 43 * @var string 44 */ 45 protected $current_enzyme; 49 46 50 47 /** … … 308 305 * 309 306 * @param string $rule 310 * @param bool $same_name307 * @param bool $same_name 311 308 * 312 309 * @return string … … 327 324 * Echo a script HTML tag to write data to the javascript console of the browser. 328 325 * 329 * @param $data326 * @param mixed $data 330 327 */ 331 328 protected 332 329 function console_log( $data ) 333 330 { 334 $json = json_encode($data); 335 $output = <<<SCRIPT 336 \n<script> 337 (function( data ) { 338 console = window.console || {}; 339 console.log = console.log || function(data){}; 340 console.log(data); 341 })( $json ); 342 </script> 343 SCRIPT; 331 $json = json_encode((is_array($data) || is_object($data)) 332 ? $data 333 : trim($data)); 334 $output = "<script>if(window.console){if(window.console.log){window.console.log($json);}}</script>"; 344 335 echo $output; 345 336 } … … 359 350 { 360 351 $this->last_eval_error = array('type' => $type, 'message' => $message, 'file' => $file, 'line' => $line); 361 return false; 352 return true; 353 } 354 355 /** 356 * Check the syntax of a code snippet. 357 * 358 * @param $code 359 * 360 * @return mixed|null|string 361 */ 362 protected 363 function php_lint( $code ) 364 { 365 $result = null; 366 if ( ! function_exists('shell_exec') ) { 367 return $result; 368 } 369 $temp = tmpfile(); 370 $meta = stream_get_meta_data($temp); 371 $filename = $meta['uri']; 372 fwrite($temp, "<?php $code"); 373 $result = shell_exec("php -n -l $filename"); // -n = no ini, -l = only lint 374 fclose($temp); 375 376 $result = trim($result); 377 $result = str_replace($filename, 'enzyme code', $result); 378 $result = str_replace("\nErrors parsing enzyme code", '', $result); 379 return $result; 362 380 } 363 381 … … 377 395 function safe_eval( $code, array $arguments = array() ) 378 396 { 379 $this->last_eval_error = null; 380 $previous_scream = ini_set('scream.enabled', false); 397 $error = $output = $exception = null; 398 $previous_ini = array(); 399 400 $previous_ini['scream.enabled'] = ini_set('scream.enabled', false); 381 401 set_error_handler(array($this, 'set_last_eval_error'), E_ALL); 382 402 ob_start(); 383 $result = @eval($code); 384 ob_end_clean(); 403 try { 404 $this->last_eval_error = null; 405 // --------------------------------------------------------------------------------------------------------- 406 $result = @eval($code); 407 // --------------------------------------------------------------------------------------------------------- 408 $error = $this->last_eval_error; 409 $this->last_eval_error = null; 410 } catch ( Exception $e ) { 411 $result = false; // Let's force the same error treatment 412 $exception = $e; // but remember the exception now. 413 } 414 $output = ob_get_clean(); 385 415 restore_error_handler(); 386 ini_set('scream.enabled', $previous_scream); 387 list($error, $this->last_eval_error) = array($this->last_eval_error, null); 388 return array($result, $error); 416 ini_set('scream.enabled', $previous_ini['scream.enabled']); 417 418 if ( false === $result ) { 419 if ( null === $error && null === $exception ) { 420 $error = $this->php_lint($code); 421 } 422 if ( null === $error ) { 423 $error = $exception; 424 } 425 } 426 // Notice that error can be null, array, string, or an Exception descendant. 427 return array($result, $error, $output); 389 428 } 390 429 … … 596 635 $this->injection_author_can(EnzymesCapabilities::use_others_custom_fields)) 597 636 ) { 598 list($result, $error) = $this->safe_eval($code, $arguments); 599 if ( is_array($error) ) { 637 list($result, $error, $output) = $this->safe_eval($code, $arguments); 638 if ( $error ) { 639 $this->console_log(__('ENZYMES ERROR')); 640 $this->console_log(sprintf(__('post: %1$s - enzyme: %3$s - injection: {[%2$s]}'), 641 $this->injection_post->ID, $this->current_sequence, $this->current_enzyme)); 600 642 $this->console_log($error); 601 643 $result = null; 602 644 } 645 if ( $output ) { 646 $this->console_log(__('ENZYMES OUTPUT')); 647 $this->console_log(sprintf(__('post: %1$s - enzyme: %3$s - injection: {[%2$s]}'), 648 $this->injection_post->ID, $this->current_sequence, $this->current_enzyme)); 649 $this->console_log($output); 650 } 603 651 } else { 604 652 $result = null; … … 621 669 $this->debug_print('executing post_item'); 622 670 // match again to be able to access groups by name... 623 $expression = $this->grammar['post_item']->wrapper_set('@@') 624 ->expression(true); 625 preg_match($expression, $post_item, $matches); 671 preg_match($this->grammar_rule('post_item'), $post_item, $matches); 626 672 $post_object = $this->wp_post($matches); 627 673 if ( ! $post_object instanceof WP_Post ) { … … 649 695 { 650 696 $this->debug_print('executing author_item'); 651 $expression = $this->grammar['author_item']->wrapper_set('@@') 652 ->expression(true); 653 preg_match($expression, $author_item, $matches); 697 preg_match($this->grammar_rule('author_item'), $author_item, $matches); 654 698 $post_object = $this->wp_post($matches); 655 699 if ( ! $post_object instanceof WP_Post ) { … … 675 719 function do_execution( $execution ) 676 720 { 721 $this->current_enzyme = $execution; 677 722 preg_match($this->grammar_rule('execution'), $execution, $matches); 678 723 $post_item = @$matches['post_item']; … … 741 786 { 742 787 $this->debug_print('transcluding post_item'); 743 $expression = $this->grammar['post_item']->wrapper_set('@@') 744 ->expression(true); 745 preg_match($expression, $post_item, $matches); 788 preg_match($this->grammar_rule('post_item'), $post_item, $matches); 746 789 $code = $this->wp_post_field($post_object, $matches); 747 790 $result = $this->transclude_code($code, $post_object); … … 762 805 { 763 806 $this->debug_print('transcluding author_item'); 764 $expression = $this->grammar['author_item']->wrapper_set('@@') 765 ->expression(true); 766 preg_match($expression, $author_item, $matches); 807 preg_match($this->grammar_rule('author_item'), $author_item, $matches); 767 808 $user_object = $this->wp_author($post_object); 768 809 $code = $this->wp_user_field($user_object, $matches); … … 789 830 $this->injection_author_can(EnzymesCapabilities::use_others_attributes) 790 831 ) { 791 $expression = $this->grammar['post_attr']->wrapper_set('@@') 792 ->expression(true); 793 preg_match($expression, $post_attr, $matches); 832 preg_match($this->grammar_rule('post_attr'), $post_attr, $matches); 794 833 $result = $this->wp_post_attribute($post_object, $matches); 795 834 } else { … … 817 856 $this->injection_author_can(EnzymesCapabilities::use_others_attributes) 818 857 ) { 819 $expression = $this->grammar['author_attr']->wrapper_set('@@') 820 ->expression(true); 821 preg_match($expression, $author_attr, $matches); 858 preg_match($this->grammar_rule('author_attr'), $author_attr, $matches); 822 859 $user_object = $this->wp_author($post_object); 823 860 $result = $this->wp_user_attribute($user_object, $matches); … … 838 875 function do_transclusion( $transclusion ) 839 876 { 877 $this->current_enzyme = $transclusion; 840 878 preg_match($this->grammar_rule('transclusion'), $transclusion, $matches); 841 879 $post_item = @$matches['post_item']; … … 980 1018 // after stripping out the forced version from $sequence, it any 981 1019 } else { 982 $this->catalyzed = new EnzymesSequence(); 983 $rest = $sequence; 1020 $this->current_sequence = $could_be_sequence; 1021 $this->catalyzed = new EnzymesSequence(); 1022 $rest = $sequence; 984 1023 while (preg_match($this->e_sequence_start, $rest, $matches)) { 985 1024 $execution = @$matches['execution']; … … 1096 1135 return $result; 1097 1136 } 1137 1138 // ----------------------------------------------------------------------------------------------------------------- 1139 1140 /** 1141 * @var bool 1142 */ 1143 public $debug_on = false; 1144 1145 /** 1146 * @param mixed $something 1147 */ 1148 public 1149 function debug_print( $something ) 1150 { 1151 if ( ! $this->debug_on ) { 1152 return; 1153 } 1154 fwrite(STDERR, "\n" . print_r($something, true) . "\n"); 1155 } 1098 1156 } -
enzymes/trunk/tests/test-Enzymes3.php
r1067352 r1068480 33 33 } 34 34 35 /** 36 * @param $name 37 * @param null $args 38 * @param null $object 39 * 40 * @return mixed 41 * @throws Exception 42 */ 35 43 function call_method( $name, $args = null, $object = null ) 36 44 { … … 127 135 function test_safe_eval_no_error() 128 136 { 129 $code = 'list($name) = $arguments; 130 echo $name; 131 return $name;'; 137 $code = ' 138 list($name) = $arguments; 139 echo $name; 140 return $name;'; 132 141 $name = 'Andrea'; 133 142 list($result, $error) = $this->call_method('safe_eval', array($code, array($name))); … … 137 146 } 138 147 139 function test_safe_eval_error() 140 { 141 $code = 'list($name) = $arguments; 142 echo name; // notice the error here 143 return $name;'; 148 function test_safe_eval_undefined_error() 149 { 150 $code = ' 151 list($name) = $arguments; 152 echo name; // notice the error here 153 return $name;'; 144 154 $name = 'Andrea'; 145 155 list($result, $error) = $this->call_method('safe_eval', array($code, array($name))); 146 156 $this->assertArrayHasKey('message', $error); 147 $message = "Use of undefined constant name - assumed 'name'"; 148 $this->assertEquals($message, $error['message']); 157 $this->assertEquals("Use of undefined constant name - assumed 'name'", $error['message']); 149 158 $this->assertEquals($name, $result); 159 $this->expectOutputString(''); 160 } 161 162 function test_safe_eval_parse_error() 163 { 164 $code = ' 165 echo $foo 166 echo $foo;'; 167 $enzymes = new Enzymes3(); 168 list(, $error, $output) = $this->call_method('safe_eval', array($code, array()), $enzymes); 169 $this->assertRegExp('@^Parse error:.+(T_ECHO).+on line 3$@m', $error); 170 $this->assertEquals('', $output); 171 $this->expectOutputString(''); 172 } 173 174 function test_safe_eval_bubbling_exception() 175 { 176 $code = ' 177 throw new Exception("What did you expect?");'; 178 $enzymes = new Enzymes3(); 179 list(, $error, $output) = $this->call_method('safe_eval', array($code, array()), $enzymes); 180 $this->assertInstanceOf('Exception', $error); 181 $this->assertEquals('What did you expect?', $error->getMessage()); 182 $this->assertEquals('', $output); 183 $this->expectOutputString(''); 184 } 185 186 function test_safe_eval_user_error() 187 { 188 $code = ' 189 trigger_error("What did you expect?", E_USER_ERROR);'; 190 $enzymes = new Enzymes3(); 191 list(, $error, $output) = $this->call_method('safe_eval', array($code, array()), $enzymes); 192 $this->assertArrayHasKey('message', $error); 193 $this->assertEquals("What did you expect?", $error['message']); 194 // $this->assertEquals('', print_r($error, true)); 195 $this->assertEquals('', $output); 196 $this->expectOutputString(''); 197 } 198 199 function test_safe_eval_parse_error2() 200 { 201 $code = ' 202 function my_function() 203 return "hello from my function"; 204 } 205 return my_function();'; 206 $enzymes = new Enzymes3(); 207 list(, $error, $output) = $this->call_method('safe_eval', array($code, array()), $enzymes); 208 $this->assertRegExp('@^Parse error:.+(T_RETURN).+on line 3$@m', $error); 209 // $this->assertEquals('', print_r($error, true)); 210 $this->assertEquals('', $output); 150 211 $this->expectOutputString(''); 151 212 }
Note: See TracChangeset
for help on using the changeset viewer.