Using a Widget as Action Provider is not passing parameters

I’m almost sure I’ve found a bug.

How to reproduce it:

Create a "Action Provider Widget", following How to use a widget as action provider and passing parameters as said in the last section "Final notes, Actions code reuse with CAction"

This is the final code:

CAction:


class saveJpg extends CAction{

    public $filepath;

    

    public function run(){

        $filepath = $this->filepath;

        print "OK: $filepath";          

    }

}

Widget (relevant part only):


public static function actions()

{

    return array(

       'saveJpg'=>'application.extensions.myext.actions.saveJpg',

    );

}

Client code Controller (relevant part only):


public function actions()

{

    return array(

        'myext.'=> array(

            'class'=>'application.extensions.myext.Myext',

            'filepath'=> 'something'

        )

    );

}

Calling url //localhost/mysite/mycontroller/myext.saveJpg prints ‘OK’ without ‘something’

1st confirmation of the bug:

I’ve tried some debugging following Mike’s suggestion

I’ve added some ‘echo’ and ‘print_r’ to framework/web/CController.php’s createActionFromMap function without changing the behaviour of the method:


	protected function createActionFromMap($actionMap,$actionID,$requestActionID,$config=array())

	{

        echo "am: "; print_r($actionMap); echo " aid: "; print_r($actionID); echo " raid: "; print_r($requestActionID); echo " conf: "; print_r($config); echo "\n\n";

		if(($pos=strpos($actionID,'.'))===false && isset($actionMap[$actionID]))

		{

			$baseConfig=is_array($actionMap[$actionID]) ? $actionMap[$actionID] : array('class'=>$actionMap[$actionID],/*'filepath'=> 'something'*/);

                        echo "bc: "; print_r($baseConfig); echo " c: "; print_r($config); echo "\n";

			return Yii::createComponent(empty($config)?$baseConfig:array_merge($baseConfig,$config),$this,$requestActionID);

		}

		else if($pos===false)

			return null;


		// the action is defined in a provider

		$prefix=substr($actionID,0,$pos+1);

		if(!isset($actionMap[$prefix]))

			return null;

		$actionID=(string)substr($actionID,$pos+1);


		$provider=$actionMap[$prefix];

		if(is_string($provider))

			$providerType=$provider;

		else if(is_array($provider) && isset($provider['class']))

		{

			$providerType=$provider['class'];

			if(isset($provider[$actionID]))

			{

				if(is_string($provider[$actionID]))

					$config=array_merge(array('class'=>$provider[$actionID]),$config);

				else

					$config=array_merge($provider[$actionID],$config);

			} 

		}

		else

			throw new CException(Yii::t('yii','Object configuration must be an array containing a "class" element.'));


		$class=Yii::import($providerType,true);

		$map=call_user_func(array($class,'actions'));

        

                echo "Poor conf: "; print_r($config); echo "\n";

		return $this->createActionFromMap($map,$actionID,$requestActionID,$config);

	}

and this is the produced output:


am: Array

(

    [jpegcam.] => Array

        (

            [class] => application.extensions.jpegcam.Jpegcam

            [filepath] => mio

        )


)

 aid: jpegcam.saveJpg raid: jpegcam.saveJpg conf: Array

(

)




Poor conf: Array

(

)


am: Array

(

    [saveJpg] => application.extensions.jpegcam.actions.saveJpg

)

 aid: saveJpg raid: jpegcam.saveJpg conf: Array

(

)




bc: Array

(

    [class] => application.extensions.jpegcam.actions.saveJpg

)

 c: Array

(

)


OK: 

As you can see the method calls itself (each call starts with ‘am:’ for $actionMap) but it looses the parameters between the first and the second call (check ‘Poor conf’ line)

2nd confirmation of the bug:

If I decomment the final part of


$baseConfig=is_array($actionMap[$actionID]) ? $actionMap[$actionID] : array('class'=>$actionMap[$actionID],/*'filepath'=> 'something'*/);

then I get the expected result: OK: something.

does it fixed in the new version 1.8?? :unsure: