Я тоже нахожу это раздражающим.
CWsdlGenerator использует отражение и специально ищет только определенные общедоступные свойства, поэтому он не найдет магические свойства, такие как отношения. Вы должны объявить их общедоступными.
Но CActiveRecord использует магическую функцию __get () для загрузки отношений. И __get () не вызывается для существующего открытого свойства, поэтому, если вы объявите их do , они никогда не загрузятся. Вы всегда должны явно загружать их, используя $ model-> STATE = $ model-> getRelated ('STATE').
Я думал о создании подкласса CWsdlGenerator и переопределении processType (), чтобы проверить наличие нового комментария к документу, чтобы позволить вам явно объявить магические свойства; но processType () является закрытым, поэтому его нельзя переопределить.
CWebServiceAction можно разделить на подклассы, и там вы можете переопределить createWebService (), чтобы установить для CWebService-> generatorConfig использование другого класса вместо CWsdlGenerator. Я создал копию с именем CWsdlGeneratorMagic и добавил 10 строк для анализа комментария к документу. Мне не нравится это решение, но оно может сработать.
В комментариях к документации класса моей модели (они объявляют волшебные свойства отношений 'HAS_MANY' pictures 'и' sources '):
/**
* The following is for the SOAP WSDL generator replacement CWsdlGeneratorMagic
* @magic Picture[] $pictures
* @magic Source[] $sources
*/
В моем классе контроллеров:
/**
* Make this a webservice
*/
public function actions() {
return array(
'api'=>array(
'class'=>'CWebServiceActionMagic',
),
);
}
в CWebServiceActionMagic.php:
protected function createWebService($provider,$wsdlUrl,$serviceUrl)
{
$a = new CWebService($provider,$wsdlUrl,$serviceUrl);
$a->generatorConfig = 'CWsdlGeneratorMagic';
return $a;
}
в CWsdlGeneratorMagic (в конце processType (), сразу после закрывающей скобки foreach ($ class-> getProperties () as $ property)):
// Handle magic properties
$comment = $class->getDocComment();
$matches = array();
if (preg_match_all('/@magic\s+([\w\.]+(\[\s*\])?)\s*?(.*)$/mi', $comment, $matches, PREG_SET_ORDER)) {
foreach ($matches as $match) {
$name = trim($match[3]);
$name = ltrim($name, '$');
$this->_types[$type][$name]=array($this->processType($match[1]),trim($match[3])); // name => type, doc
}
}
// end handling of magic properties
return 'tns:'.$type;
Я думаю, что можно установитьогенератор CWebService в файле конфигурации приложения, чтобы вам не понадобился CWebServiceActionMagic, но я не смог заставить его работать.
Объявления @magic в основном повторяют объявления @property, но только для тех, которые я хочу раскрыть в WSDL. (Вероятно, следует назвать это @soapmagic или что-то вроде этого).