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 | ||||
| ------------------------ | ||||
|  | ||||
| - 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 #17473: Fixed `SimpleConditionBuilder::build()` when column is not a string (alexkart) | ||||
| - Bug #17486: Fixed error when using `batch()` without `$db` parameter with MSSQL (alexkart) | ||||
|  | ||||
| @ -27,6 +27,10 @@ class Behavior extends BaseObject | ||||
|      */ | ||||
|     public $owner; | ||||
|  | ||||
|     /** | ||||
|      * @var Array Attached events handlers | ||||
|      */ | ||||
|     private $_attachedEvents = []; | ||||
|  | ||||
|     /** | ||||
|      * Declares event handlers for the [[owner]]'s events. | ||||
| @ -72,6 +76,7 @@ class Behavior extends BaseObject | ||||
|     { | ||||
|         $this->owner = $owner; | ||||
|         foreach ($this->events() as $event => $handler) { | ||||
|             $this->_attachedEvents[$event] = $handler; | ||||
|             $owner->on($event, is_string($handler) ? [$this, $handler] : $handler); | ||||
|         } | ||||
|     } | ||||
| @ -85,9 +90,10 @@ class Behavior extends BaseObject | ||||
|     public function detach() | ||||
|     { | ||||
|         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->_attachedEvents = []; | ||||
|             $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->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 | ||||
|  | ||||
| @ -494,7 +494,7 @@ class ModelTest extends TestCase | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         $model = include 'stub/AnonymousModelClass.php'; | ||||
|         $model = require __DIR__ . '/stub/AnonymousModelClass.php'; | ||||
|  | ||||
|         $this->expectException('yii\base\InvalidConfigException'); | ||||
|         $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