mirror of
				https://github.com/yiisoft/yii2.git
				synced 2025-10-31 18:47:33 +08:00 
			
		
		
		
	Fix #17223: Fixed detaching a behavior event when it is a Closure instance
This commit is contained in:
		 Nikolay Poryadin
					Nikolay Poryadin
				
			
				
					committed by
					
						 Alexander Makarov
						Alexander Makarov
					
				
			
			
				
	
			
			
			 Alexander Makarov
						Alexander Makarov
					
				
			
						parent
						
							14a7198434
						
					
				
				
					commit
					491f9737fe
				
			| @ -4,6 +4,7 @@ Yii Framework 2 Change Log | |||||||
| 2.0.25 under development | 2.0.25 under development | ||||||
| ------------------------ | ------------------------ | ||||||
|  |  | ||||||
|  | - Bug #17223: Fixed detaching a behavior event when it is a Closure instance (GHopperMSK, rob006) | ||||||
| - Bug #15779: If directory path is passed to `FileHelper::unlink()` and directory has files it will not delete files in this directory on Windows now (alexkart) | - Bug #15779: If directory path is passed to `FileHelper::unlink()` and directory has files it will not delete files in this directory on Windows now (alexkart) | ||||||
| - Bug #17473: Fixed `SimpleConditionBuilder::build()` when column is not a string (alexkart) | - Bug #17473: Fixed `SimpleConditionBuilder::build()` when column is not a string (alexkart) | ||||||
| - Bug #17486: Fixed error when using `batch()` without `$db` parameter with MSSQL (alexkart) | - Bug #17486: Fixed error when using `batch()` without `$db` parameter with MSSQL (alexkart) | ||||||
|  | |||||||
| @ -27,6 +27,10 @@ class Behavior extends BaseObject | |||||||
|      */ |      */ | ||||||
|     public $owner; |     public $owner; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @var Array Attached events handlers | ||||||
|  |      */ | ||||||
|  |     private $_attachedEvents = []; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Declares event handlers for the [[owner]]'s events. |      * Declares event handlers for the [[owner]]'s events. | ||||||
| @ -72,6 +76,7 @@ class Behavior extends BaseObject | |||||||
|     { |     { | ||||||
|         $this->owner = $owner; |         $this->owner = $owner; | ||||||
|         foreach ($this->events() as $event => $handler) { |         foreach ($this->events() as $event => $handler) { | ||||||
|  |             $this->_attachedEvents[$event] = $handler; | ||||||
|             $owner->on($event, is_string($handler) ? [$this, $handler] : $handler); |             $owner->on($event, is_string($handler) ? [$this, $handler] : $handler); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @ -85,9 +90,10 @@ class Behavior extends BaseObject | |||||||
|     public function detach() |     public function detach() | ||||||
|     { |     { | ||||||
|         if ($this->owner) { |         if ($this->owner) { | ||||||
|             foreach ($this->events() as $event => $handler) { |             foreach ($this->_attachedEvents as $event => $handler) { | ||||||
|                 $this->owner->off($event, is_string($handler) ? [$this, $handler] : $handler); |                 $this->owner->off($event, is_string($handler) ? [$this, $handler] : $handler); | ||||||
|             } |             } | ||||||
|  |             $this->_attachedEvents = []; | ||||||
|             $this->owner = null; |             $this->owner = null; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -445,6 +445,25 @@ class ComponentTest extends TestCase | |||||||
|         $this->assertFalse($obj->off('test', [$this, 'handler2']), 'Trying to remove the handler that is not attached'); |         $this->assertFalse($obj->off('test', [$this, 'handler2']), 'Trying to remove the handler that is not attached'); | ||||||
|         $this->assertTrue($obj->off('test', [$this, 'handler']), 'Trying to remove the attached handler'); |         $this->assertTrue($obj->off('test', [$this, 'handler']), 'Trying to remove the attached handler'); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @see https://github.com/yiisoft/yii2/issues/17223 | ||||||
|  |      */ | ||||||
|  |     public function testEventClosureDetachesItself() | ||||||
|  |     { | ||||||
|  |         if (PHP_VERSION_ID < 70000) { | ||||||
|  |             $this->markTestSkipped('Can not be tested on PHP < 7.0'); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         $obj = require __DIR__ . '/stub/AnonymousComponentClass.php'; | ||||||
|  |  | ||||||
|  |         $obj->trigger('barEventOnce'); | ||||||
|  |         $this->assertEquals(1, $obj->foo); | ||||||
|  |         $obj->trigger('barEventOnce'); | ||||||
|  |         $this->assertEquals(1, $obj->foo); | ||||||
|  |     } | ||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
| class NewComponent extends Component | class NewComponent extends Component | ||||||
|  | |||||||
| @ -494,7 +494,7 @@ class ModelTest extends TestCase | |||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         $model = include 'stub/AnonymousModelClass.php'; |         $model = require __DIR__ . '/stub/AnonymousModelClass.php'; | ||||||
|  |  | ||||||
|         $this->expectException('yii\base\InvalidConfigException'); |         $this->expectException('yii\base\InvalidConfigException'); | ||||||
|         $this->expectExceptionMessage('The "formName()" method should be explicitly defined for anonymous models'); |         $this->expectExceptionMessage('The "formName()" method should be explicitly defined for anonymous models'); | ||||||
|  | |||||||
							
								
								
									
										21
									
								
								tests/framework/base/stub/AnonymousComponentClass.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								tests/framework/base/stub/AnonymousComponentClass.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,21 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | $obj = new class () extends \yii\base\Component | ||||||
|  | { | ||||||
|  |     public $foo = 0; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | $obj->attachBehavior('bar', (new class () extends \yii\base\Behavior | ||||||
|  | { | ||||||
|  |     public function events() | ||||||
|  |     { | ||||||
|  |         return [ | ||||||
|  |             'barEventOnce' => function ($event) { | ||||||
|  |                 $this->owner->foo++; | ||||||
|  |                 $this->detach(); | ||||||
|  |             }, | ||||||
|  |         ]; | ||||||
|  |     } | ||||||
|  | })); | ||||||
|  |  | ||||||
|  | return $obj; | ||||||
		Reference in New Issue
	
	Block a user