Особенности межплагинного взаимодействия

Конечно, вызывать методы классов плагина из другого плагина не очень хорошо. Но, тем не менее. Чтобы впоследствии не было мучительно больно, при объявлении связей между моделями, надо всегда указывать свойство className, причем полностью, т.е. ‘Plugin.MyModel’. Иначе возможны весьма забавные эффекты. Справедливо для версий 1.2 и 1.3. Дальше немного кода.

Есть два плагина: PluginOne и PluginTwo. У первого две связанные модели: PluginOneModelOne belongsTo PluginOneModelTwo. У второго плагина одна модель, связанная с первой моделью первого плагина (пусть тоже будет belongsTo, неважно): PluginTwoModelOne belongsTo PluginOneModelOne. Соответственно, объявлено все это вот так:

Файл /plugins/plugin_one/models/plugin_one_model_one.php

class PluginOneModelOne extends PluginOneAppModel {
 
	var $belongsTo = array('PluginOneModelTwo');
 
}

Файл /plugins/plugin_one/models/plugin_one_model_two.php

class PluginOneModelTwo extends PluginOneAppModel {
	var $actsAs = array('Tree');
}

Файл /plugins/plugin_two/models/plugin_two_model_one.php

class PluginTwoModelOne extends PluginTwoAppModel {
 
	var $belongsTo = array(
		'PluginOneModelOne'=>array(
			'className'=>'PluginOne.PluginOneModelOne'
		));
 
}

Создадим в контроллере второго плагина тестовый метод:

Файл /plugins/plugin_two/controllers/plugin_two_model_ones_controller.php

class PluginTwoModelOnesController extends PluginTwoAppController {
 
	function typeofmodel() {
		die(get_class($this->PluginTwoModelOne->PluginOneModelOne->PluginOneModelTwo));
	}
 
}

Опачки! Третья модель типа AppModel, а не PluginOneModelTwo! Соответственно, не загружаются behaviours, перечисленные в $actsAs, не работают методы модели, не обрабатываются правила валидации. Хитрый Cake молча создает объект базового класса, чтоб связь работала для стандартной выборки, записи и все.

Достаточно в описании связи моделей первого плагина полностью указать какой класс использовать — все отлично начинает работать. Меняем код PluginOneModelOne

Файл /plugins/plugin_one/models/plugin_one_model_one.php

class PluginOneModelOne extends PluginOneAppModel {
 
	var $belongsTo = array(
			'PluginOneModelTwo'=>array(
				'className'=>'PluginOne.PluginOneModelTwo'
		));
 
}

и запускаем снова тестовый метод. Вот теперь все как и ожидается.

Если подумать, то поведение фреймворка в общем-то логичное. Он ищет класс в текущем плагине и у самого приложения. Хотя мог бы и предупреждать, пусть бы и только в отладочном режиме, что есть проблема.

Опубликовано 07.11.2010 в 14:08 · Автор Сергей · Ссылка
Рубрики: CakePHP · Теги: , , , ,