/** * Fügt ein Property hinzu * * added das Property, seine Setter und gegebenfalls auch einen Eintrag im Constructor */ public function compile(GClass $gClass, $flags = 0x0) { // das ist okay, wenn man getters oder setters oder den constructor adden will (imo) //if ($gClass->hasProperty($this->property->name)) { // throw new \InvalidArgumentException('Property: '.$this->property->name. ' besteht bereits in Klasse '.$gClass); //} $this->createClassBuilder($gClass); $this->cProperty = $this->classBuilder->addProperty($this->property->name, $this->property->type); if ($this->property->upcaseName) { $this->cProperty->setUpcaseName($this->property->upcaseName); } if ($this->generateSetter) { $this->classBuilder->generateSetter($this->cProperty, NULL, ClassBuilder::INHERIT); } if ($this->generateGetter) { $this->classBuilder->generateGetter($this->cProperty, NULL, ClassBuilder::INHERIT); } if (($cs = $this->generateInConstructor) !== FALSE) { $constructor = $this->classBuilder->getConstructor(TRUE); if (!$constructor->hasParameter($this->property->name)) { $parameter = new GParameter($this->property->name, $this->property->type ? $this->property->type->getPHPHint() : NULL, $this->constructorDefaultValue); $constructor->addParameter($parameter, $this->generateInConstructor); if ($this->dependencyInjection === self::DEPENDENCY_INJECTION_CONSTRUCTOR) { if (!$this->property->type instanceof ObjectType || !$this->property->type->hasClass()) { throw new \InvalidArgumentException('Wenn DependencyInjection CONSTRUCTOR ist, muss der property-type ein ObjectType sein mit einer Klasse. Type ist: ' . Code::varInfo($this->property->type)); } $objectValue = new Expression(sprintf('$%s ?: new %s()', $parameter->getName(), $this->property->type->getGClass()->getClassName())); } else { $objectValue = new AST\Variable($parameter->getName(), new AST\LType('Mixed')); } $constructor->appendBodyLines(array($this->codeWriter->callSetter(new AST\Variable('this', new AST\LType('Object')), $this->cProperty->getUpcaseName(), $objectValue) . ';')); } } $this->classBuilder->generateDocBlocks(); return $gClass; }
/** * Erstellt die i18nAPI für ein i18nProperty * * i18nPropertyName ist title: * * erstellt einen virtuellen Getter für den OriginalNamen des Properties (getTitle($lang)) * erstellt einen virtuellen Setter für den OriginalNamen des Properties (setTitle($value, $lang)) * * setI18nTitle(Array $titles); * getI18nTitle() -> array * gibt es schon * * zusätzlich müssen wir die Properties (welche nicht im MetaSet sind) erstellen: * titleDe, titleEn, usw je nach $this->languages * alle ohne getter */ public function generateI18nAPI(ClassBuilderProperty $property, $originalName, $originalFlags = 0x0, $originalUpperCaseName = NULL) { $originalType = $property->getType()->getType(); $properties = array(); foreach ($this->getLanguages() as $lang) { $properties[$lang] = $this->createProperty($originalName . ucfirst($lang), $originalType, $originalFlags & (self::NULLABLE | self::UNIQUE) | self::WITHOUT_GETTER | self::WITHOUT_SETTER, $originalUpperCaseName ? $originalUpperCaseName . ucfirst($lang) : NULL); $this->setForcedMetaProperty($properties[$lang], FALSE); // nicht in die meta exportieren, weil wir sie da nicht wollen, das i18n-property schon! } // wir müssen den initialisierungs code für den i18n array in den getter injecten $initCode = array(); $initCode[] = sprintf('if (count($this->%s) == 0) {', $property->getName()); foreach ($this->getLanguages() as $lang) { $initCode[] = sprintf(' $this->%s[\'%s\'] = $this->%s;', $property->getName(), $lang, $properties[$lang]->getName()); } $initCode[] = '}'; $this->getMethod($property->getGetterName())->beforeBody($initCode); // wir müssen den setter für den i18n Array injecten (der soll die virtuellen properties setzen) $updateCode = array(); foreach ($this->getLanguages() as $lang) { $updateCode[] = sprintf('$this->%s = $this->%s[\'%s\'];', $properties[$lang]->getName(), $property->getName(), $lang); } $this->getMethod($property->getSetterName())->insertBody($updateCode, -1); // vor: return $this; // dann müssen wir getField $getCode = array(); $getCode[] = sprintf('$title = $this->%s();', $property->getGetterName()); $getCode[] = 'return $title[$lang];'; $this->addMethod(new GMethod('get' . ($originalUpperCaseName ?: ucfirst($originalName)), array(new GParameter('lang', NULL)), $getCode)); // und setField bauen $setCode = array(); // wir könnten uns noch überlegen bei else: eine exception zu schmeissen? foreach ($this->getLanguages() as $key => $lang) { if ($key === 0) { $setCode[] = sprintf('if ($lang === \'%s\') {', $lang); } else { $setCode[] = sprintf('} elseif ($lang === \'%s\') {', $lang); } // setze klassenVariable und i18nVariable auf den neuen Wert $setCode[] = sprintf(' $this->%s = $this->%s[\'%s\'] = $value;', $properties[$lang]->getName(), $property->getName(), $lang); } $setCode[] = '}'; $setCode[] = 'return $this;'; $this->addMethod(new GMethod('set' . ($originalUpperCaseName ?: ucfirst($originalName)), array(new GParameter('value', $originalType->getPHPHint()), new GParameter('lang', NULL)), $setCode)); }
public function getProperty($name) { if (!array_key_exists($key = mb_strtolower($name), $this->properties)) { // elevate if ($this->class->hasProperty($name)) { $this->addProperty($property = new ClassBuilderProperty($name, $this, $this->class->getProperty($name))); $property->setWasElevated(TRUE); } else { throw new NoSuchPropertyClassBuilderException(sprintf(" Property '%s' ist nicht vorhanden", $name)); } } return $this->properties[$key]; }