Best Atoum code snippet using extension.getName
RoundTrip.php
Source:RoundTrip.php
...138 /** @var $previousDomainObjects \EBT\ExtensionBuilder\Domain\Model\DomainObject[] */139 foreach ($previousDomainObjects as $oldDomainObject) {140 $this->previousDomainObjects[$oldDomainObject->getUniqueIdentifier()] = $oldDomainObject;141 $this->log(142 'Old domain object: ' . $oldDomainObject->getName() . ' - ' . $oldDomainObject->getUniqueIdentifier(),143 0,144 $jsonConfig145 );146 }147 /**148 * now we store all renamed domainObjects in an array to enable149 * detection of renaming in relationProperties (property->getForeignModel)150 * we also build an array with the new unique identifiers to detect151 * deleting of domainObjects152 */153 $currentDomainsObjects = [];154 foreach ($this->extension->getDomainObjects() as $domainObject) {155 /** @var \EBT\ExtensionBuilder\Domain\Model\DomainObject $domainObject */156 if (isset($this->previousDomainObjects[$domainObject->getUniqueIdentifier()])) {157 if ($this->previousDomainObjects[$domainObject->getUniqueIdentifier()]->getName() != $domainObject->getName()) {158 $renamedDomainObjects[$domainObject->getUniqueIdentifier()] = $domainObject;159 }160 }161 $currentDomainsObjects[$domainObject->getUniqueIdentifier()] = $domainObject;162 }163 // remove deleted objects164 foreach ($previousDomainObjects as $oldDomainObject) {165 if (!isset($currentDomainsObjects[$oldDomainObject->getUniqueIdentifier()])) {166 $this->removeDomainObjectFiles($oldDomainObject);167 }168 }169 }170 }171 /**172 * This method is the main part of the roundtrip functionality173 * It looks for a previous version of the current domain object and174 * parses the existing class file for that domain model175 * compares all properties and methods with the previous version.176 *177 * Methods are either removed/added or updated according to178 * the new property names179 *180 * @param \EBT\ExtensionBuilder\Domain\Model\DomainObject $currentDomainObject181 *182 * @return \EBT\ExtensionBuilder\Domain\Model\File|null OR null183 * @throws \Exception184 */185 public function getDomainModelClassFile(Model\DomainObject $currentDomainObject)186 {187 if (isset($this->previousDomainObjects[$currentDomainObject->getUniqueIdentifier()])) {188 $this->log('domainObject identified:' . $currentDomainObject->getName());189 $oldDomainObject = $this->previousDomainObjects[$currentDomainObject->getUniqueIdentifier()];190 /** @var \EBT\ExtensionBuilder\Domain\Model\DomainObject $oldDomainObject */191 $extensionDir = $this->previousExtensionDirectory;192 $fileName = FileGenerator::getFolderForClassFile($extensionDir, 'Model',193 false) . $oldDomainObject->getName() . '.php';194 if (file_exists($fileName)) {195 // import the classObject from the existing file196 $this->classFileObject = $this->parserService->parseFile($fileName);197 $this->classObject = $this->classFileObject->getFirstClass();198 if ($oldDomainObject->getName() != $currentDomainObject->getName() || $this->extensionRenamed) {199 if (!$this->extensionRenamed) {200 $this->log('domainObject renamed. old: ' . $oldDomainObject->getName() . ' new: ' . $currentDomainObject->getName(),201 'extension_builder');202 }203 $newClassName = $currentDomainObject->getName();204 $this->classObject->setName($newClassName);205 $this->classObject->setFileName($currentDomainObject->getName() . '.php');206 $this->cleanUp(FileGenerator::getFolderForClassFile($extensionDir, 'Model'),207 $oldDomainObject->getName() . '.php');208 $this->cleanUp($extensionDir . 'Configuration/TCA/', $oldDomainObject->getName() . '.php');209 } else {210 $this->classObject->setName($currentDomainObject->getName());211 }212 $this->updateModelClassProperties($oldDomainObject, $currentDomainObject);213 $newActions = [];214 foreach ($currentDomainObject->getActions() as $newAction) {215 $newActions[$newAction->getName()] = $newAction;216 }217 $oldActions = $oldDomainObject->getActions();218 if ((empty($newActions) && !$currentDomainObject->isAggregateRoot())219 && (!empty($oldActions) || $oldDomainObject->isAggregateRoot())220 ) {221 // remove the controller222 $this->cleanUp(223 FileGenerator::getFolderForClassFile($extensionDir, 'Controller'),224 $oldDomainObject->getName() . 'Controller.php'225 );226 }227 // the parent class settings configuration228 $parentClass = $currentDomainObject->getParentClass();229 $oldParentClass = $oldDomainObject->getParentClass();230 if (!empty($parentClass)) {231 if ($oldParentClass != $parentClass) {232 // the parent class was just new added233 $this->classObject->setParentClassName($parentClass);234 }235 } elseif (!empty($oldParentClass)) {236 // the old object had a parent class setting, but it's removed now237 if ($currentDomainObject->isEntity()) {238 $parentClass = $this->configurationManager->getParentClassForEntityObject($this->extension->getExtensionKey());239 } else {240 $parentClass = $this->configurationManager->getParentClassForValueObject($this->extension->getExtensionKey());241 }242 $this->classObject->setParentClassName($parentClass);243 }244 if ($currentDomainObject->isEntity() && !$oldDomainObject->isEntity()) {245 // the object type was changed in the modeler246 $this->classObject->setParentClassName(247 $this->configurationManager->getParentClassForEntityObject($this->extension->getExtensionKey())248 );249 } elseif (!$currentDomainObject->isEntity() && $oldDomainObject->isEntity()) {250 // the object type was changed in the modeler251 $this->classObject->setParentClassName(252 $this->configurationManager->getParentClassForValueObject($this->extension->getExtensionKey())253 );254 }255 $this->classFileObject->setClasses([$this->classObject]);256 if ($this->extension->vendorNameChanged()) {257 $this->updateVendorName();258 }259 return $this->classFileObject;260 }261 } else {262 $this->log('domainObject not identified:' . $currentDomainObject->getName(), 0,263 $this->previousDomainObjects);264 $fileName = FileGenerator::getFolderForClassFile($this->extensionDirectory, 'Model', false);265 $fileName .= $currentDomainObject->getName() . '.php';266 if (file_exists($fileName)) {267 // import the classObject from the existing file268 $this->classFileObject = $this->parserService->parseFile($fileName);269 $this->classObject = $this->classFileObject->getFirstClass();270 $this->classObject->setFileName($fileName);271 $this->classObject->setName($currentDomainObject->getName());272 $this->log('class file found:' . $currentDomainObject->getName() . '.php', 0,273 $this->classObject->getNamespaceName());274 $this->classFileObject->setClasses([$this->classObject]);275 return $this->classFileObject;276 }277 }278 return null;279 }280 /**281 * @param \EBT\ExtensionBuilder\Domain\Model\DomainObject $currentDomainObject282 *283 * @return \EBT\ExtensionBuilder\Domain\Model\File|null284 * @throws \EBT\ExtensionBuilder\Exception\FileNotFoundException285 * @throws \Exception286 */287 public function getControllerClassFile(Model\DomainObject $currentDomainObject)288 {289 $extensionDir = $this->previousExtensionDirectory;290 if (isset($this->previousDomainObjects[$currentDomainObject->getUniqueIdentifier()])) {291 $oldDomainObject = $this->previousDomainObjects[$currentDomainObject->getUniqueIdentifier()];292 $fileName = FileGenerator::getFolderForClassFile($extensionDir, 'Controller', false);293 $fileName .= $oldDomainObject->getName() . 'Controller.php';294 if (file_exists($fileName)) {295 $this->classFileObject = $this->parserService->parseFile($fileName);296 $this->classObject = $this->classFileObject->getFirstClass();297 $this->classObject->setName($currentDomainObject->getName() . 'Controller');298 if ($oldDomainObject->getName() != $currentDomainObject->getName() || $this->extensionRenamed) {299 $this->mapOldControllerToCurrentClassObject($oldDomainObject, $currentDomainObject);300 } elseif ($oldDomainObject->isAggregateRoot() && !$currentDomainObject->isAggregateRoot()) {301 $injectMethodName = 'inject' . lcfirst($oldDomainObject->getName()) . 'Repository';302 $this->classObject->removeMethod($injectMethodName);303 }304 $newActions = [];305 foreach ($currentDomainObject->getActions() as $newAction) {306 $newActions[$newAction->getName()] = $newAction;307 }308 $oldActions = $oldDomainObject->getActions();309 if (isset($this->previousDomainObjects[$currentDomainObject->getUniqueIdentifier()])) {310 // now we remove old action methods311 foreach ($oldActions as $oldAction) {312 if (!isset($newActions[$oldAction->getName()])) {313 // an action was removed314 $this->classObject->removeMethod($oldAction->getName() . 'Action');315 $this->log('Action method removed:' . $oldAction->getName(), 0,316 $this->classObject->getMethods());317 }318 }319 // we don't have to add new ones, this will be done automatically by the class builder320 }321 if ($this->extension->vendorNameChanged()) {322 $this->updateVendorName();323 }324 $this->classFileObject->setClasses([$this->classObject]);325 return $this->classFileObject;326 } else {327 return null;328 }329 } else {330 $fileName = FileGenerator::getFolderForClassFile($extensionDir, 'Controller', false);331 $fileName .= $currentDomainObject->getName() . 'Controller.php';332 if (file_exists($fileName)) {333 $this->classFileObject = $this->parserService->parseFile($fileName);334 $this->classObject = $this->classFileObject->getFirstClass();335 $this->classObject->setFileName($fileName);336 $className = $currentDomainObject->getControllerClassName();337 $this->classObject->setName($className);338 if ($this->extension->vendorNameChanged()) {339 $this->updateVendorName();340 }341 $this->classFileObject->setClasses([$this->classObject]);342 return $this->classFileObject;343 } else {344 $this->log('No existing controller class:' . $fileName, 2);345 }346 }347 $this->log('No existing controller class:' . $currentDomainObject->getName(), 2);348 return null;349 }350 /**351 * update all relevant namespace parts in tags, typehints etc.352 */353 protected function updateVendorName()354 {355 $this->classObject->setNamespaceName($this->renameVendor($this->classObject->getNamespaceName()));356 foreach ($this->classObject->getProperties() as $property) {357 foreach ($property->getTags() as $tagName => $tagValue) {358 if (is_array($tagValue)) {359 $tagValue = $tagValue[0];360 }361 if (!empty($tagValue)) {362 $tagValue = $this->renameVendor($tagValue);363 $property->setTag($tagName, $tagValue, true);364 }365 }366 }367 foreach ($this->classObject->getMethods() as $method) {368 foreach ($method->getTags() as $tagName => $tagValue) {369 if (is_array($tagValue)) {370 $tagValue = $tagValue[0];371 }372 if (!empty($tagValue)) {373 $tagValue = $this->renameVendor($tagValue);374 $method->setTag($tagName, $tagValue, true);375 }376 }377 foreach ($method->getParameters() as $parameter) {378 $typeHint = $parameter->getTypeHint();379 if (!empty($typeHint)) {380 $parameter->setTypeHint($this->renameVendor($typeHint));381 }382 $varType = $parameter->getVarType();383 if (!empty($varType)) {384 $parameter->setVarType($this->renameVendor($varType));385 }386 }387 }388 }389 protected function renameVendor($string)390 {391 return str_replace('\\' . $this->extension->getOriginalVendorName() . '\\',392 '\\' . $this->extension->getVendorName() . '\\', $string);393 }394 /**395 * If a domainObject was renamed396 *397 * @param \EBT\ExtensionBuilder\Domain\Model\DomainObject $oldDomainObject398 * @param \EBT\ExtensionBuilder\Domain\Model\DomainObject $currentDomainObject399 *400 * @return void401 * @throws \Exception402 */403 protected function mapOldControllerToCurrentClassObject(404 Model\DomainObject $oldDomainObject,405 Model\DomainObject $currentDomainObject406 ) {407 $extensionDir = $this->previousExtensionDirectory;408 $newClassName = $currentDomainObject->getName() . 'Controller';409 $newName = $currentDomainObject->getName();410 $oldName = $oldDomainObject->getName();411 $this->classObject->setName($newClassName);412 $this->classObject->setDescription($this->replaceUpperAndLowerCase($oldName, $newName,413 $this->classObject->getDescription()));414 if ($oldDomainObject->isAggregateRoot()) {415 // should we keep the old properties comments and tags?416 $this->classObject->removeProperty(lcfirst($oldName) . 'Repository');417 $injectMethodName = 'inject' . $oldName . 'Repository';418 if ($currentDomainObject->isAggregateRoot()) {419 // update the initializeAction method body420 $initializeMethod = $this->classObject->getMethod('initializeAction');421 if ($initializeMethod != null) {422 $initializeMethodBodyStmts = $initializeMethod->getBodyStmts();423 $initializeMethodBodyStmts = str_replace(424 lcfirst($oldName) . 'Repository',425 lcfirst($newName) . 'Repository',426 $initializeMethodBodyStmts427 );428 $initializeMethod->setBodyStmts($initializeMethodBodyStmts);429 $this->classObject->setMethod($initializeMethod);430 }431 $injectMethod = $this->classObject->getMethod($injectMethodName);432 if ($injectMethod != null) {433 $this->classObject->removeMethod($injectMethodName);434 $initializeMethodBodyStmts = str_replace(435 lcfirst($oldName),436 lcfirst($newName),437 $injectMethod->getBodyStmts()438 );439 $injectMethod->setBodyStmts($initializeMethodBodyStmts);440 $injectMethod->setTag('param',441 $currentDomainObject->getFullyQualifiedDomainRepositoryClassName() . ' $' . $newName . 'Repository');442 $injectMethod->setName('inject' . $newName . 'Repository');443 $parameter = new Model\ClassObject\MethodParameter(lcfirst($newName) . 'Repository');444 $parameter->setTypeHint($currentDomainObject->getFullyQualifiedDomainRepositoryClassName());445 $parameter->setPosition(0);446 $injectMethod->replaceParameter($parameter);447 $this->classObject->setMethod($injectMethod);448 }449 foreach ($oldDomainObject->getActions() as $action) {450 // here we have to update all the occurences of domain object names in action methods451 $actionMethod = $this->classObject->getMethod($action->getName() . 'Action');452 if ($actionMethod != null) {453 $actionMethodBody = $actionMethod->getBodyStmts();454 $newActionMethodBody = str_replace(455 lcfirst($oldName) . 'Repository',456 lcfirst($newName) . 'Repository',457 $actionMethodBody458 );459 $actionMethod->setBodyStmts($newActionMethodBody);460 $actionMethod->setTag('param', $currentDomainObject->getQualifiedClassName());461 $parameters = $actionMethod->getParameters();462 foreach ($parameters as &$parameter) {463 if (strpos($parameter->getTypeHint(), $oldDomainObject->getFullQualifiedClassName()) > -1) {464 $parameter->setTypeHint($currentDomainObject->getFullQualifiedClassName());465 $parameter->setName($this->replaceUpperAndLowerCase($oldName, $newName,466 $parameter->getName()));467 $actionMethod->replaceParameter($parameter);468 }469 }470 $tags = $actionMethod->getTags();471 foreach ($tags as $tagName => $tagValue) {472 $tags[$tagName] = $this->replaceUpperAndLowerCase($oldName, $newName, $tagValue);473 }474 $actionMethod->setTags($tags);475 $actionMethod->setDescription($this->replaceUpperAndLowerCase($oldName, $newName,476 $actionMethod->getDescription()));477 //TODO: this is not safe. Could rename unwanted variables478 $actionMethod->setBodyStmts($this->replaceUpperAndLowerCase($oldName, $newName,479 $actionMethod->getBodyStmts()));480 $this->classObject->setMethod($actionMethod);481 }482 }483 } else {484 $this->classObject->removeMethod('initializeAction');485 $this->classObject->removeMethod($injectMethodName);486 $this->cleanUp(FileGenerator::getFolderForClassFile($extensionDir, 'Repository'),487 $oldName . 'Repository.php');488 }489 }490 $this->classObject->setFileName($newName . 'Controller.php');491 $this->cleanUp(FileGenerator::getFolderForClassFile($extensionDir, 'Controller'), $oldName . 'Controller.php');492 }493 /**494 * @param \EBT\ExtensionBuilder\Domain\Model\DomainObject $currentDomainObject495 *496 * @return \EBT\ExtensionBuilder\Domain\Model\File|null497 * @throws \EBT\ExtensionBuilder\Exception\FileNotFoundException498 * @throws \Exception499 */500 public function getRepositoryClassFile(Model\DomainObject $currentDomainObject)501 {502 $extensionDir = $this->previousExtensionDirectory;503 if (isset($this->previousDomainObjects[$currentDomainObject->getUniqueIdentifier()])) {504 $oldDomainObject = $this->previousDomainObjects[$currentDomainObject->getUniqueIdentifier()];505 $fileName = FileGenerator::getFolderForClassFile($extensionDir, 'Repository', false);506 $fileName .= $oldDomainObject->getName() . 'Repository.php';507 if (file_exists($fileName)) {508 $this->classFileObject = $this->parserService->parseFile($fileName);509 $this->classObject = $this->classFileObject->getFirstClass();510 $this->classObject->setName($currentDomainObject->getName() . 'Repository');511 if ($oldDomainObject->getName() != $currentDomainObject->getName() || $this->extensionRenamed) {512 $newClassName = $currentDomainObject->getDomainRepositoryClassName();513 $this->classObject->setName($newClassName);514 $this->cleanUp(515 FileGenerator::getFolderForClassFile($extensionDir, 'Repository'),516 $oldDomainObject->getName() . 'Repository.php'517 );518 }519 return $this->classFileObject;520 }521 } else {522 $fileName = FileGenerator::getFolderForClassFile($extensionDir, 'Repository', false);523 $fileName .= $currentDomainObject->getName() . 'Repository.php';524 if (file_exists($fileName)) {525 $this->classFileObject = $this->parserService->parseFile($fileName);526 $this->classObject = $this->classFileObject->getFirstClass();527 $this->classObject->setFileName($fileName);528 $this->classObject->setFileName($fileName);529 $this->log('existing Repository class:' . $fileName, 0, (array)$this->classObject);530 return $this->classFileObject;531 }532 }533 $this->log('No existing Repository class:' . $currentDomainObject->getName(), 2);534 return null;535 }536 /**537 * Compare the properties of each object and remove/update538 * the properties and the related methods539 *540 * @param \EBT\ExtensionBuilder\Domain\Model\DomainObject $oldDomainObject541 * @param \EBT\ExtensionBuilder\Domain\Model\DomainObject $newDomainObject542 *543 * return void (all actions are performed on $this->classObject544 */545 protected function updateModelClassProperties(546 Model\DomainObject $oldDomainObject,547 Model\DomainObject $newDomainObject548 ) {549 $newProperties = [];550 foreach ($newDomainObject->getProperties() as $property) {551 $newProperties[$property->getUniqueIdentifier()] = $property;552 }553 // compare all old properties with new ones554 foreach ($oldDomainObject->getProperties() as $oldProperty) {555 /* @var Model\DomainObject\AbstractProperty $oldProperty556 * @var Model\DomainObject\AbstractProperty $newProperty557 */558 if (isset($newProperties[$oldProperty->getUniqueIdentifier()])) {559 $newProperty = $newProperties[$oldProperty->getUniqueIdentifier()];560 // relation type changed561 if ($oldProperty->isAnyToManyRelation() != $newProperty->isAnyToManyRelation()) {562 // remove old methods since we won't convert getter and setter methods563 //to add/remove methods564 if ($oldProperty->isAnyToManyRelation()) {565 $this->classObject->removeMethod('add' . ucfirst(Inflector::singularize($oldProperty->getName())));566 $this->classObject->removeMethod('remove' . ucfirst(Inflector::singularize($oldProperty->getName())));567 }568 $this->classObject->removeMethod('get' . ucfirst($oldProperty->getName()));569 $this->classObject->removeMethod('set' . ucfirst($oldProperty->getName()));570 if ($oldProperty->isBoolean()) {571 $this->classObject->removeMethod('is' . ucfirst(Inflector::singularize($oldProperty->getName())));572 }573 $this->classObject->removeProperty($oldProperty->getName());574 $this->log(575 'property type changed => removed old property:' . $oldProperty->getName(),576 1577 );578 } else {579 $this->updateProperty($oldProperty, $newProperty);580 $newDomainObject->getPropertyByName($newProperty->getName())->setNew(false);581 }582 } else {583 $this->removePropertyAndRelatedMethods($oldProperty);584 }585 }586 }587 /**588 * Removes all related methods, if a property was removed589 * @param \EBT\ExtensionBuilder\Domain\Model\DomainObject\AbstractProperty $propertyToRemove590 *591 * @return void592 */593 protected function removePropertyAndRelatedMethods($propertyToRemove)594 {595 $propertyName = $propertyToRemove->getName();596 $this->classObject->removeProperty($propertyName);597 if ($propertyToRemove->isAnyToManyRelation()) {598 $this->classObject->removeMethod('add' . ucfirst(Inflector::singularize($propertyName)));599 $this->classObject->removeMethod('remove' . ucfirst(Inflector::singularize($propertyName)));600 }601 $this->classObject->removeMethod('get' . ucfirst($propertyName));602 $this->classObject->removeMethod('set' . ucfirst($propertyName));603 if ($propertyToRemove->isBoolean()) {604 $this->classObject->removeMethod('is' . ucfirst($propertyName));605 }606 }607 /**608 * Rename a property and update comment (var tag and description)609 * @param \EBT\ExtensionBuilder\Domain\Model\DomainObject\AbstractProperty $oldProperty610 * @param \EBT\ExtensionBuilder\Domain\Model\DomainObject\AbstractProperty $newProperty611 *612 * @return void613 */614 protected function updateProperty($oldProperty, $newProperty)615 {616 $classProperty = $this->classObject->getProperty($oldProperty->getName());617 if ($classProperty) {618 $classProperty->setName($newProperty->getName());619 $classProperty->setTag('var', $newProperty->getTypeForComment());620 $newDescription = $newProperty->getDescription();621 if (empty($newDescription) || $newDescription == $newProperty->getName()) {622 $newDescription = str_replace($oldProperty->getName(), $newProperty->getName(),623 $classProperty->getDescription());624 }625 $classProperty->setDescription($newDescription);626 $this->classObject->removeProperty($oldProperty->getName());627 $this->classObject->setProperty($classProperty);628 if ($this->relatedMethodsNeedUpdate($oldProperty, $newProperty)) {629 $this->updatePropertyRelatedMethods($oldProperty, $newProperty);630 }631 }632 }633 /**634 * @param \EBT\ExtensionBuilder\Domain\Model\DomainObject\AbstractProperty $oldProperty635 * @param \EBT\ExtensionBuilder\Domain\Model\DomainObject\AbstractProperty $newProperty636 *637 * @return bool638 */639 protected function relatedMethodsNeedUpdate($oldProperty, $newProperty)640 {641 if ($this->extensionRenamed) {642 return true;643 }644 if ($newProperty->getName() != $oldProperty->getName()) {645 $this->log('property renamed:' . $oldProperty->getName() . ' ' . $newProperty->getName());646 return true;647 }648 if ($newProperty->getTypeForComment() != $this->updateExtensionKey($oldProperty->getTypeForComment())) {649 $this->log(650 'property type changed from ' . $this->updateExtensionKey($oldProperty->getTypeForComment())651 . ' to ' . $newProperty->getTypeForComment()652 );653 return true;654 }655 if ($newProperty->isRelation()) {656 /** @var $oldProperty \EBT\ExtensionBuilder\Domain\Model\DomainObject\Relation\AbstractRelation */657 // if only the related domain object was renamed658 $previousClassName = $this->updateExtensionKey($oldProperty->getForeignClassName());659 if ($this->getForeignClassName($newProperty) != $previousClassName) {660 $this->log(661 'related domainObject was renamed:' . $previousClassName . ' ->' . $this->getForeignClassName($newProperty)662 );663 return true;664 }665 }666 return false;667 }668 /**669 * replace occurences of the old extension key with the new one670 * used to compare classNames671 * @param $stringToParse672 * @return string673 */674 protected function updateExtensionKey($stringToParse)675 {676 if (!$this->extensionRenamed) {677 return $stringToParse;678 }679 $separatorToken = '\\\\';680 if (strpos($stringToParse, $separatorToken) === false) {681 $separatorToken = '_';682 }683 $result = str_replace(684 $separatorToken . ucfirst($this->previousExtensionKey) . $separatorToken,685 $separatorToken . ucfirst($this->extension->getExtensionKey()) . $separatorToken,686 $stringToParse687 );688 return $result;689 }690 /**691 * @param \EBT\ExtensionBuilder\Domain\Model\DomainObject\AbstractProperty $oldProperty692 * @param \EBT\ExtensionBuilder\Domain\Model\DomainObject\AbstractProperty $newProperty693 *694 * @return void695 */696 protected function updatePropertyRelatedMethods($oldProperty, $newProperty)697 {698 if ($newProperty->isAnyToManyRelation()) {699 $this->updateMethod($oldProperty, $newProperty, 'add');700 $this->updateMethod($oldProperty, $newProperty, 'remove');701 }702 $this->updateMethod($oldProperty, $newProperty, 'get');703 $this->updateMethod($oldProperty, $newProperty, 'set');704 if ($newProperty->isBoolean()) {705 $this->updateMethod($oldProperty, $newProperty, 'is');706 }707 if ($newProperty->getTypeForComment() != $this->updateExtensionKey($oldProperty->getTypeForComment())) {708 if ($oldProperty->isBoolean() && !$newProperty->isBoolean()) {709 $this->classObject->removeMethod(ClassBuilder::getMethodName($oldProperty, 'is'));710 $this->log(711 'Method removed:' . ClassBuilder::getMethodName($oldProperty, 'is'),712 1,713 $this->classObject->getMethods()714 );715 }716 }717 }718 /**719 * update means renaming of method name, parameter and replacing720 * parameter names in method body721 *722 * @param \EBT\ExtensionBuilder\Domain\Model\DomainObject\AbstractProperty $oldProperty723 * @param \EBT\ExtensionBuilder\Domain\Model\DomainObject\AbstractProperty $newProperty724 * @param string $methodType get,set,add,remove,is725 *726 * @return void727 */728 protected function updateMethod($oldProperty, $newProperty, $methodType)729 {730 $oldMethodName = ClassBuilder::getMethodName($oldProperty, $methodType);731 // the method to be merged732 $mergedMethod = $this->classObject->getMethod($oldMethodName);733 if (!$mergedMethod) {734 // no previous version of the method exists735 return;736 }737 $newMethodName = ClassBuilder::getMethodName($newProperty, $methodType);738 $this->log('updateMethod:' . $oldMethodName . '=>' . $newMethodName, 'extension_builder');739 if ($oldProperty->getName() != $newProperty->getName()) {740 // rename the method741 $mergedMethod->setName($newMethodName);742 $oldMethodBody = $mergedMethod->getBodyStmts();743 $newMethodBody = $this->replacePropertyNameInMethodBody($oldProperty->getName(), $newProperty->getName(),744 $oldMethodBody);745 $mergedMethod->setBodyStmts($newMethodBody);746 }747 // update the method parameters748 $methodParameters = $mergedMethod->getParameters();749 if (!empty($methodParameters)) {750 $parameterTags = $mergedMethod->getTagValues('param');751 foreach ($methodParameters as $methodParameter) {752 $oldParameterName = $methodParameter->getName();753 if ($oldParameterName == ClassBuilder::getParameterName($oldProperty, $methodType)) {754 $newParameterName = ClassBuilder::getParameterName($newProperty, $methodType);755 $methodParameter->setName($newParameterName);756 $newMethodBody = $this->replacePropertyNameInMethodBody($oldParameterName, $newParameterName,757 $mergedMethod->getBodyStmts());758 $mergedMethod->setBodyStmts($newMethodBody);759 }760 $typeHint = $methodParameter->getTypeHint();761 if ($typeHint) {762 if ($oldProperty->isRelation()) {763 /** @var $oldProperty \EBT\ExtensionBuilder\Domain\Model\DomainObject\Relation\AbstractRelation */764 if ($typeHint == $oldProperty->getForeignClassName()) {765 $methodParameter->setTypeHint($this->updateExtensionKey($this->getForeignClassName($newProperty)));766 }767 }768 }769 $parameterTags[$methodParameter->getPosition()] = ClassBuilder::getParamTag($newProperty, $methodType);770 $mergedMethod->replaceParameter($methodParameter);771 }772 $mergedMethod->setTag('param', $parameterTags);773 }774 if ($mergedMethod->isTaggedWith('return') && $mergedMethod->getTagValue('return') != 'void') {775 $mergedMethod->setTag('return', $newProperty->getTypeForComment() . ' ' . $newProperty->getName());776 }777 // replace property names in description778 $mergedMethod->setDescription(str_replace($oldProperty->getName(), $newProperty->getName(),779 $mergedMethod->getDescription()));780 if ($oldProperty instanceof AbstractRelation && $newProperty instanceof AbstractRelation) {781 $mergedMethod->setDescription(782 str_replace(783 $oldProperty->getForeignClassName(),784 $newProperty->getForeignClassName(),785 $mergedMethod->getDescription()786 )787 );788 }789 $this->classObject->removeMethod($oldMethodName);790 $this->classObject->addMethod($mergedMethod);791 }792 /**793 * @param string $search794 * @param string $replace795 * @param string $haystack796 *797 * @return string[] with replaced values798 */799 protected function replaceUpperAndLowerCase($search, $replace, $haystack)800 {801 $result = str_replace(ucfirst($search), ucfirst($replace), $haystack);802 $result = str_replace(lcfirst($search), lcfirst($replace), $result);803 return $result;804 }805 /**806 * Replace all occurrences of the old property name with the new name807 *808 * @param string $oldName809 * @param string $newName810 * @param string[] $methodBodyStmts811 *812 * @return array813 */814 protected function replacePropertyNameInMethodBody($oldName, $newName, $methodBodyStmts)815 {816 return $this->parserService->replaceNodeProperty(817 $methodBodyStmts,818 [$oldName => $newName]819 );820 }821 /**comments822 * if the foreign DomainObject was renamed, the relation has to be updated also823 *824 * @param \EBT\ExtensionBuilder\Domain\Model\DomainObject\Relation\AbstractRelation $relation825 * @return string className of foreign class826 */827 public function getForeignClassName($relation)828 {829 if ($relation->getForeignModel() && isset($this->renamedDomainObjects[$relation->getForeignModel()->getUniqueIdentifier()])) {830 /** @var $renamedObject \EBT\ExtensionBuilder\Domain\Model\DomainObject */831 $renamedObject = $this->renamedDomainObjects[$relation->getForeignModel()->getUniqueIdentifier()];832 return $renamedObject->getQualifiedClassName();833 } else {834 return $relation->getForeignClassName();835 }836 }837 /**838 * remove domainObject related files if a domainObject was deleted839 *840 * @param \EBT\ExtensionBuilder\Domain\Model\DomainObject $domainObject841 *842 * @return void843 * @throws \Exception844 */845 protected function removeDomainObjectFiles(Model\DomainObject $domainObject)846 {847 $this->log('Remove domainObject ' . $domainObject->getName());848 $this->cleanUp(849 FileGenerator::getFolderForClassFile($this->previousExtensionDirectory, 'Model', false),850 $domainObject->getName() . '.php'851 );852 $this->cleanUp($this->previousExtensionDirectory . 'Configuration/TCA/', $domainObject->getName() . '.php');853 if ($domainObject->isAggregateRoot()) {854 $this->cleanUp(855 FileGenerator::getFolderForClassFile($this->previousExtensionDirectory, 'Controller', false),856 $domainObject->getName() . 'Controller.php'857 );858 $this->cleanUp(859 FileGenerator::getFolderForClassFile($this->previousExtensionDirectory, 'Repository', false),860 $domainObject->getName() . 'Repository.php'861 );862 }863 if (count($domainObject->getActions()) > 0) {864 $this->cleanUp(865 FileGenerator::getFolderForClassFile($this->previousExtensionDirectory, 'Controller', false),866 $domainObject->getName() . 'Controller.php'867 );868 }869 // other files870 $iconsDirectory = $this->extensionDirectory . 'Resources/Public/Icons/';871 $languageDirectory = $this->extensionDirectory . 'Resources/Private/Language/';872 $locallang_cshFile = $languageDirectory . 'locallang_csh_' . $domainObject->getDatabaseTableName() . '.xml';873 $iconFile = $iconsDirectory . $domainObject->getDatabaseTableName() . '.gif';874 if (file_exists($locallang_cshFile)) {875 // no overwrite settings check here...876 unlink($locallang_cshFile);877 }878 if (file_exists($iconFile)) {879 unlink($iconFile);880 }881 }882 /**883 * remove class files that are not required any more, due to884 * renaming of ModelObjects or changed types885 * @param string $path886 * @param string $fileName887 * @return void888 */889 public function cleanUp($path, $fileName)890 {891 if ($this->extensionRenamed) {892 // wo won't delete the old extension!893 return;894 }895 if (!is_file($path . $fileName)) {896 GeneralUtility::devLog('cleanUp File not found: ' . $path . $fileName, 'extension_builder', 1);897 return;898 }899 unlink($path . $fileName);900 }901 /**902 * @return array903 */904 public static function getExtConfiguration()905 {906 $extConfiguration = unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['extension_builder']);907 return $extConfiguration;908 }909 /**910 * finds a related overwrite setting to a path911 * and returns the overWrite setting912 * -1 for do not create at all913 * 0 for overwrite914 * 1 for merge (if possible)915 * 2 for keep existing file916 *917 * @param string $path of the file to get the settings for918 * @param \EBT\ExtensionBuilder\Domain\Model\Extension $extension919 *920 * @return int overWriteSetting921 * @throws \Exception922 */923 public static function getOverWriteSettingForPath($path, $extension)924 {925 $map = [926 'skip' => -1,927 'merge' => 1,928 'keep' => 2929 ];930 $settings = $extension->getSettings();931 if (!is_array($settings)) {932 throw new \Exception('overWrite settings could not be parsed');933 }934 if (strpos($path, $extension->getExtensionDir()) === 0) {935 $path = str_replace($extension->getExtensionDir(), '', $path);936 }937 $pathParts = explode('/', $path);938 $overWriteSettings = $settings['overwriteSettings'];939 foreach ($pathParts as $pathPart) {940 if (isset($overWriteSettings[$pathPart]) && is_array($overWriteSettings[$pathPart])) {941 // step one level deeper942 $overWriteSettings = $overWriteSettings[$pathPart];943 } else {944 return $map[$overWriteSettings[$pathPart]];945 }946 }947 return 0;948 }949 /**950 * parse existing tca and set appropriate properties951 *952 * @param \EBT\ExtensionBuilder\Domain\Model\Extension $extension953 *954 * @return void955 * @throws \Exception956 */957 public static function prepareExtensionForRoundtrip(&$extension)958 {959 foreach ($extension->getDomainObjects() as $domainObject) {960 $existingTca = self::getTcaForDomainObject($domainObject);961 if ($existingTca) {962 foreach ($domainObject->getAnyToManyRelationProperties() as $relationProperty) {963 if (isset($existingTca['columns'][$relationProperty->getName()]['config']['MM'])) {964 self::log(965 'Relation table for Model ' . $domainObject->getName() . ' relation ' . $relationProperty->getName(),966 0,967 $existingTca['columns'][$relationProperty->getName()]['config']968 );969 $relationProperty->setRelationTableName(970 $existingTca['columns'][$relationProperty->getName()]['config']['MM']971 );972 }973 }974 }975 if (file_exists($extension->getExtensionDir() . 'Configuration/TCA/' . $domainObject->getName() . '.php')) {976 $extensionConfigurationJson = ExtensionBuilderConfigurationManager::getExtensionBuilderJson($extension->getExtensionKey());977 if (floatval($extensionConfigurationJson['log']['extension_builder_version']) <= 6.2) {978 self::moveAdditionalTcaToOverrideFile($domainObject);979 }980 }981 }982 }983 /**984 * Returns the current TCA for a domain objects table if the985 * extension is installed986 * TODO: check for previous table name if an extension is renamed987 *988 * @param \EBT\ExtensionBuilder\Domain\Model\DomainObject $domainObject989 *990 * @return array991 */992 protected static function getTcaForDomainObject($domainObject)993 {994 $tableName = $domainObject->getDatabaseTableName();995 if (isset($GLOBALS['TCA'][$tableName])) {996 return $GLOBALS['TCA'][$tableName];997 } else {998 return null;999 }1000 }1001 /**1002 * Move custom TCA in files generated by EB versions <= 6.21003 * to the appropriate overrides files1004 *1005 * @param \EBT\ExtensionBuilder\Domain\Model\DomainObject $domainObject1006 *1007 * @throws \Exception1008 */1009 public static function moveAdditionalTcaToOverrideFile($domainObject)1010 {1011 $tcaDir = $domainObject->getExtension()->getExtensionDir() . 'Configuration/TCA/';1012 $existingTcaFile = $tcaDir . $domainObject->getName() . '.php';1013 if (file_exists($existingTcaFile)) {1014 $existingFileContent = file_get_contents($existingTcaFile);1015 $fileParts = explode(self::SPLIT_TOKEN, $existingFileContent);1016 if (count($fileParts) === 2) {1017 $customFileContent = str_replace('$TCA[', '$GLOBALS[\'TCA\'][', $fileParts[1]);1018 $customFileContent = '<?php ' . LF . self::SPLIT_TOKEN . LF . str_replace('?>', '', $customFileContent);1019 if (!empty($customFileContent)) {1020 $overrideDir = $tcaDir . 'Overrides/';1021 if (!is_dir($overrideDir)) {1022 GeneralUtility::mkdir_deep($tcaDir, 'Overrides');1023 }1024 $success = GeneralUtility::writeFile($overrideDir . $domainObject->getDatabaseTableName() . '.php',1025 $customFileContent);1026 if (!$success) {...
ExtensionValidator.php
Source:ExtensionValidator.php
...242 /** @var $plugin \EBT\ExtensionBuilder\Domain\Model\Plugin */243 foreach ($extension->getPlugins() as $plugin) {244 if (self::validatePluginKey($plugin->getKey()) === 0) {245 $this->validationResult['errors'][] = new \Exception(246 'Invalid plugin key in plugin ' . $plugin->getName() . ': "' . $plugin->getKey() . '".' . LF .247 'Only alphanumeric character without spaces are allowed',248 self::ERROR_PLUGIN_INVALID_KEY249 );250 }251 if (in_array($plugin->getKey(), $pluginKeys)) {252 $this->validationResult['errors'][] = new \Exception(253 'Duplicate plugin key: "' . $plugin->getKey() . '". Plugin keys must be unique.',254 self::ERROR_PLUGIN_DUPLICATE_KEY255 );256 }257 $pluginKeys[] = $plugin->getKey();258 $this->validatePluginConfiguration($plugin, $extension);259 }260 }261 /**262 * @param \EBT\ExtensionBuilder\Domain\Model\Plugin $plugin263 * @param \EBT\ExtensionBuilder\Domain\Model\Extension $extension264 * @return void265 */266 private function validatePluginConfiguration($plugin, $extension)267 {268 $controllerActionCombinationConfiguration = $plugin->getControllerActionCombinations();269 if (is_array($controllerActionCombinationConfiguration)) {270 $firstControllerAction = true;271 foreach ($controllerActionCombinationConfiguration as $controllerName => $actionNames) {272 $this->validateActionConfiguration($controllerName, $actionNames, 'plugin ' . $plugin->getName(),273 $extension, $firstControllerAction);274 $firstControllerAction = false;275 }276 }277 $noncachableActionConfiguration = $plugin->getNoncacheableControllerActions();278 if (is_array($noncachableActionConfiguration)) {279 foreach ($noncachableActionConfiguration as $controllerName => $actionNames) {280 $this->validateActionConfiguration($controllerName, $actionNames, 'plugin ' . $plugin->getName(),281 $extension);282 }283 }284 $switchableActionConfiguration = $plugin->getSwitchableControllerActions();285 if (is_array($switchableActionConfiguration)) {286 foreach ($switchableActionConfiguration as $switchableAction) {287 $configuredActions = [];288 foreach ($switchableAction['actions'] as $actions) {289 // Format should be: Controller->action290 list($controllerName, $actionName) = explode('->', $actions);291 $configuredActions[] = $actionName;292 $this->validateActionConfiguration($controllerName, [$actionName], 'plugin ' . $plugin->getName(),293 $extension);294 }295 $this->validateDependentActions($configuredActions, 'plugin ' . $plugin->getName());296 }297 }298 }299 /**300 * @param \EBT\ExtensionBuilder\Domain\Model\BackendModule $backendModule301 * @param \EBT\ExtensionBuilder\Domain\Model\Extension $extension302 * @return void303 */304 private function validateBackendModuleConfiguration($backendModule, $extension)305 {306 $controllerActionCombinationConfiguration = $backendModule->getControllerActionCombinations();307 if (is_array($controllerActionCombinationConfiguration)) {308 $firstControllerAction = true;309 foreach ($controllerActionCombinationConfiguration as $controllerName => $actionNames) {310 $this->validateActionConfiguration($controllerName, $actionNames, 'module ' . $backendModule->getName(),311 $extension, $firstControllerAction);312 $firstControllerAction = false;313 }314 }315 }316 private function validateDependentActions($actionNames, $name)317 {318 if ((in_array('new', $actionNames) && !in_array('create', $actionNames)) ||319 (in_array('create', $actionNames) && !in_array('new', $actionNames))320 ) {321 $this->validationResult['warnings'][] = new ExtensionException(322 'Potential misconfiguration in ' . $name . ':' . LF . 'Actions new and create usually depend on each other',323 self::ERROR_ACTION_MISCONFIGURATION324 );325 }326 if ((in_array('edit', $actionNames) && !in_array('update', $actionNames)) ||327 (in_array('update', $actionNames) && !in_array('edit', $actionNames))328 ) {329 $this->validationResult['warnings'][] = new ExtensionException(330 'Potential misconfiguration in ' . $name . ':' . LF . 'Actions edit and update usually depend on each other',331 self::ERROR_ACTION_MISCONFIGURATION332 );333 }334 }335 /**336 * @param string $controllerName337 * @param array $actionNames338 * @param string $label related plugin or module339 * @param \EBT\ExtensionBuilder\Domain\Model\Extension $extension340 * @param bool $firstControllerAction341 * @return void342 */343 private function validateActionConfiguration(344 $controllerName,345 $actionNames,346 $label,347 $extension,348 $firstControllerAction = false349 ) {350 if ($firstControllerAction) {351 // the first Controller action config is the default Controller action352 // we show a warning if that's an action that requires a domain object as parameter353 $defaultAction = reset($actionNames);354 if (in_array($defaultAction, ['show', 'edit'])) {355 $this->validationResult['warnings'][] = new ExtensionException(356 'Potential misconfiguration in ' . $label . ':' . LF .357 'Default action ' . $controllerName . '->' . $defaultAction . ' can not be called without a domain object parameter',358 self::ERROR_ACTION_MISCONFIGURATION359 );360 }361 }362 $relatedDomainObject = $extension->getDomainObjectByName($controllerName);363 if (!$relatedDomainObject) {364 $this->validationResult['warnings'][] = new ExtensionException(365 'Potential misconfiguration in ' . $label . ':' . LF . 'Controller ' . $controllerName . ' has no related Domain Object',366 self::ERROR_ACTION_MISCONFIGURATION367 );368 } else {369 $existingActions = $relatedDomainObject->getActions();370 $existingActionNames = [];371 foreach ($existingActions as $existingAction) {372 $existingActionNames[] = $existingAction->getName();373 }374 foreach ($actionNames as $actionName) {375 if (!in_array($actionName, $existingActionNames)) {376 $this->validationResult['warnings'][] = new ExtensionException(377 'Potential misconfiguration in ' . $label . ':' . LF . 'Controller ' . $controllerName . ' has no action named ' . $actionName,378 self::ERROR_ACTION_MISCONFIGURATION379 );380 }381 }382 }383 }384 /**385 * @param array $configuration386 * @return array387 */388 public function validateConfigurationFormat($configuration)389 {390 foreach ($configuration['properties']['plugins'] as $pluginConfiguration) {391 $pluginName = $pluginConfiguration['name'];392 if (!empty($pluginConfiguration['actions'])) {393 $configTypes = ['controllerActionCombinations', 'noncacheableActions'];394 foreach ($configTypes as $configType) {395 if (!empty($pluginConfiguration['actions'][$configType])) {396 $isValid = $this->validateActionConfigFormat($pluginConfiguration['actions'][$configType]);397 if (!$isValid) {398 $this->validationResult['warnings'][] = new ExtensionException(399 'Wrong format in configuration for ' . $configType . ' in plugin ' . $pluginName,400 self::ERROR_MISCONFIGURATION401 );402 }403 }404 }405 if (!empty($pluginConfiguration['actions']['switchableActions'])) {406 $isValid = true;407 $lines = GeneralUtility::trimExplode(LF, $pluginConfiguration['actions']['switchableActions'],408 true);409 $firstLine = true;410 foreach ($lines as $line) {411 if ($firstLine) {412 // label for flexform select413 if (!preg_match('/^[a-zA-Z0-9_\-\s]*$/', $line)) {414 $isValid = false;415 }416 $firstLine = false;417 } else {418 $parts = GeneralUtility::trimExplode(';', $line, true);419 if (count($parts) < 1) {420 $isValid = false;421 }422 foreach ($parts as $part) {423 if (!empty($part) && count(GeneralUtility::trimExplode('->', $part, true)) != 2) {424 $isValid = false;425 }426 }427 $firstLine = true;428 }429 }430 if (!$isValid) {431 $this->validationResult['warnings'][] = new ExtensionException(432 'Wrong format in configuration for switchable ControllerActions in plugin ' . $pluginName,433 self::ERROR_MISCONFIGURATION434 );435 }436 }437 }438 }439 foreach ($configuration['properties']['backendModules'] as $moduleConfiguration) {440 $moduleName = $moduleConfiguration['name'];441 if (!empty($moduleConfiguration['actions'])) {442 $configTypes = ['controllerActionCombinations'];443 foreach ($configTypes as $configType) {444 if (!empty($moduleConfiguration['actions'][$configType])) {445 $isValid = $this->validateActionConfigFormat($moduleConfiguration['actions'][$configType]);446 if (!$isValid) {447 $this->validationResult['warnings'][] = new ExtensionException(448 'Wrong format in configuration for ' . $configType . ' in module ' . $moduleName,449 self::ERROR_MISCONFIGURATION450 );451 }452 }453 }454 }455 }456 foreach ($configuration['modules'] as $domainObjectConfiguration) {457 $propertyNames = [];458 if (isset($domainObjectConfiguration['value']['propertyGroup']['properties'])) {459 foreach ($domainObjectConfiguration['value']['propertyGroup']['properties'] as $property) {460 if (in_array($property['propertyName'], $propertyNames)) {461 $this->validationResult['errors'][] = new ExtensionException(462 'Property "' . $property['propertyName'] . '" of Model "' . $domainObjectConfiguration['value']['name'] . '" exists twice.',463 self::ERROR_PROPERTY_DUPLICATE464 );465 }466 $propertyNames[] = $property['propertyName'];467 }468 }469 // check relation names, since these will result in class properties too470 if (isset($domainObjectConfiguration['value']['relationGroup']['relations'])) {471 foreach ($domainObjectConfiguration['value']['relationGroup']['relations'] as $property) {472 if (in_array($property['relationName'], $propertyNames)) {473 $this->validationResult['errors'][] = new ExtensionException(474 'Property "' . $property['relationName'] . '" of Model "' . $domainObjectConfiguration['value']['name'] . '" exists twice.',475 self::ERROR_PROPERTY_DUPLICATE476 );477 }478 $propertyNames[] = $property['relationName'];479 }480 }481 }482 return $this->validationResult;483 }484 /**485 * @param string $configuration486 * @return bool487 */488 protected function validateActionConfigFormat($configuration)489 {490 $isValid = true;491 $lines = GeneralUtility::trimExplode(LF, $configuration, true);492 foreach ($lines as $line) {493 $test = GeneralUtility::trimExplode('=>', $line, true);494 if (count($test) != 2) {495 $isValid = false;496 } elseif (!preg_match('/^[a-zA-Z0-9_,\s]*$/', $test[1])) {497 $isValid = false;498 }499 }500 return $isValid;501 }502 /**503 * @param \EBT\ExtensionBuilder\Domain\Model\Extension $extension504 * @return void505 */506 private function validateBackendModules($extension)507 {508 if (count($extension->getBackendModules()) < 1) {509 return;510 }511 $backendModuleKeys = [];512 /** @var $backendModule \EBT\ExtensionBuilder\Domain\Model\BackendModule */513 foreach ($extension->getBackendModules() as $backendModule) {514 if (self::validateModuleKey($backendModule->getKey()) === 0) {515 $this->validationResult['errors'][] = new \Exception(516 'Invalid key in backend module "' . $backendModule->getName() . LF . '". Only alphanumeric character without spaces are allowed',517 self::ERROR_BACKENDMODULE_INVALID_KEY518 );519 }520 if (in_array($backendModule->getKey(), $backendModuleKeys)) {521 $this->validationResult['errors'][] = new \Exception(522 'Duplicate backend module key: "' . $backendModule->getKey() . LF . '". Backend module keys must be unique.',523 self::ERROR_BACKENDMODULE_DUPLICATE_KEY524 );525 }526 $backendModuleKeys[] = $backendModule->getKey();527 $this->validateBackendModuleConfiguration($backendModule, $extension);528 }529 }530 /**531 * @param \EBT\ExtensionBuilder\Domain\Model\Extension $extension532 * @return void533 */534 private function validateDomainObjects($extension)535 {536 $actionCounter = 0;537 foreach ($extension->getDomainObjects() as $domainObject) {538 $actionCounter .= count($domainObject->getActions());539 // Check if domainObject name is given540 if (!$domainObject->getName()) {541 $this->validationResult['errors'][] = new ExtensionException(542 'A Domain Object has no name',543 self::ERROR_DOMAINOBJECT_NO_NAME544 );545 }546 /**547 * Character test548 * Allowed characters are: a-z (lowercase), A-Z (uppercase) and 0-9549 */550 if (!preg_match('/^[a-zA-Z0-9]*$/', $domainObject->getName())) {551 $this->validationResult['errors'][] = new ExtensionException(552 'Illegal domain object name "' . $domainObject->getName() . '". Please use UpperCamelCase, no spaces or underscores.',553 self::ERROR_DOMAINOBJECT_ILLEGAL_CHARACTER554 );555 }556 $objectName = $domainObject->getName();557 $firstChar = $objectName{0};558 if (strtolower($firstChar) == $firstChar) {559 $this->validationResult['errors'][] = new ExtensionException(560 'Illegal first character of domain object name "' . $domainObject->getName() . '". Please use UpperCamelCase.',561 self::ERROR_DOMAINOBJECT_LOWER_FIRST_CHARACTER562 );563 }564 if (ValidationService::isReservedExtbaseWord($objectName)) {565 $this->validationResult['errors'][] = new ExtensionException(566 'Domain object name "' . $domainObject->getName() . '" may not be used in extbase.',567 self::ERROR_PROPERTY_RESERVED_WORD568 );569 }570 $this->validateProperties($domainObject);571 $this->validateDomainObjectActions($domainObject);572 $this->validateMapping($domainObject);573 }574 if ($actionCounter < 1) {575 if (count($extension->getBackendModules()) > 0) {576 $this->validationResult['warnings'][] = new ExtensionException(577 'Potential misconfiguration: No actions configured!' . LF . 'This will result in a missing default action in your backend module',578 self::ERROR_ACTION_MISCONFIGURATION579 );580 }581 if (count($extension->getPlugins()) > 0) {582 $this->validationResult['warnings'][] = new ExtensionException(583 'Potential misconfiguration: No actions configured!' . LF . 'This will result in a missing default action in your plugin',584 self::ERROR_ACTION_MISCONFIGURATION585 );586 }587 }588 }589 /**590 * cover all cases:591 * 1. extend TYPO3 class like fe_users (no mapping table needed)592 *593 * @param \EBT\ExtensionBuilder\Domain\Model\DomainObject $domainObject594 *595 * @throws \TYPO3\CMS\Extbase\Configuration\Exception\InvalidConfigurationTypeException596 */597 private function validateMapping(DomainObject $domainObject)598 {599 $parentClass = $domainObject->getParentClass();600 $tableName = $domainObject->getMapToTable();601 $extensionPrefix = 'Tx_' . $domainObject->getExtension()->getExtensionName() . '_Domain_Model_';602 if (!empty($parentClass)) {603 $classConfiguration = $this->configurationManager->getExtbaseClassConfiguration($parentClass);604 if (!isset($classConfiguration['tableName'])) {605 if (!$tableName) {606 $this->validationResult['errors'][] = new ExtensionException(607 'Mapping configuration error in domain object ' . $domainObject->getName() . ': ' . LF .608 'The mapping table could not be detected from Extbase Configuration. Please enter a table name',609 self::ERROR_MAPPING_NO_TABLE610 );611 }612 } else {613 // get the table name from the parent class configuration614 $tableName = $classConfiguration['tableName'];615 }616 if (!class_exists($parentClass, true)) {617 $this->validationResult['errors'][] = new ExtensionException(618 'Mapping configuration error in domain object ' . $domainObject->getName() . ': the parent class ' . LF .619 $parentClass . 'seems not to exist ',620 self::ERROR_MAPPING_NO_PARENTCLASS621 );622 }623 }624 if ($tableName) {625 if (in_array($tableName, ['tt_content', 'pages']) || preg_match('/^(pages_|be_|sys_|static_|cf_)/',626 $tableName)) {627 $this->validationResult['warnings'][] = new ExtensionException(628 'The configuration for table "' . $tableName . '" is not compatible' . LF .629 ' with extbase. You have to configure it yourself if you want to map' . LF .630 ' to this table',631 self::ERROR_MAPPING_TO_INCOMPATIBLE_TABLE632 );633 }634 if (strpos($extensionPrefix, $tableName) !== false) {635 // the domainObject extends a class of the same extension636 if (!$parentClass) {637 $this->validationResult['errors'][] = new ExtensionException(638 'Mapping configuration error in domain object ' . $domainObject->getName() . ': you have to define' . LF .639 'a parent class if you map to a table of another domain object of the same extension ',640 self::ERROR_MAPPING_NO_PARENTCLASS641 );642 }643 }644 if (!isset($GLOBALS['TCA'][$tableName])) {645 $this->validationResult['errors'][] = new ExtensionException(646 'There is no entry for table "' . $tableName . '" of ' . $domainObject->getName() . ' in TCA. ' . LF .647 'For technical reasons you can only extend tables with TCA configuration.',648 self::ERROR_MAPPING_NO_TCA649 );650 }651 }652 if (isset($GLOBALS['TCA'][$tableName]['ctrl']['type'])) {653 $columns = $this->getDatabaseConnection($tableName)->getSchemaManager()->listTableColumns($tableName);654 foreach ($columns as $column) {655 if ($column->getName() === $GLOBALS['TCA'][$tableName]['ctrl']['type']) {656 if ((String)$column->getType() === 'Integer') {657 $this->validationResult['warnings'][] = new ExtensionException(658 'This means the type field can not be used for defining the record type. ' . LF .659 'You have to configure the mappings yourself if you want to map to this' . LF .660 'table or extend the correlated class',661 self::ERROR_MAPPING_WRONG_TYPEFIELD_CONFIGURATION662 );663 }664 }665 }666 }667 }668 /**669 * $actions = $domainObject->getActions();670 * @param \EBT\ExtensionBuilder\Domain\Model\DomainObject $domainObject671 * @return void672 */673 private function validateDomainObjectActions(DomainObject $domainObject)674 {675 $actionNames = [];676 $actions = $domainObject->getActions();677 foreach ($actions as $action) {678 if (in_array($action->getName(), $actionNames)) {679 $this->validationResult['errors'][] = new ExtensionException(680 'Duplicate action name "' . $action->getName() . '" of ' . $domainObject->getName() . LF .681 '; action names have to be unique for each model',682 self::ERROR_ACTIONNAME_DUPLICATE683 );684 }685 /**686 * Character test687 * Allowed characters are: a-z (lowercase), A-Z (uppercase) and 0-9688 */689 if (!preg_match('/^[a-zA-Z0-9]*$/', $action->getName())) {690 $this->validationResult['errors'][] = new ExtensionException(691 'Illegal action name "' . $action->getName() . '" of ' . $domainObject->getName() . '.' . LF .692 'Please use lowerCamelCase, no spaces or underscores.',693 self::ERROR_ACTIONNAME_ILLEGAL_CHARACTER694 );695 }696 $actionNames[] = $action->getName();697 }698 $this->validateDependentActions($actionNames, 'Domain object ' . $domainObject->getName());699 $firstAction = reset($actionNames);700 if ($firstAction == 'show' || $firstAction == 'edit' || $firstAction == 'delete') {701 $this->validationResult['warnings'][] = new ExtensionException(702 'Potential misconfiguration in Domain object ' . $domainObject->getName() . ':' . LF .703 'First action could not be default action since "' . $firstAction . '" action needs a parameter',704 self::ERROR_ACTION_MISCONFIGURATION705 );706 }707 }708 /**709 * @param \EBT\ExtensionBuilder\Domain\Model\DomainObject $domainObject710 * @return void711 */712 private function validateProperties($domainObject)713 {714 $propertyNames = [];715 foreach ($domainObject->getProperties() as $property) {716 // Check if property name is given717 if (!$property->getName()) {718 $this->validationResult['errors'][] = new ExtensionException(719 'A property of ' . $domainObject->getName() . ' has no name',720 self::ERROR_PROPERTY_NO_NAME721 );722 }723 $propertyName = $property->getName();724 /**725 * Character test726 * Allowed characters are: a-z (lowercase), A-Z (uppercase) and 0-9727 */728 if (!preg_match('/^[a-zA-Z0-9]*$/', $propertyName)) {729 $this->validationResult['errors'][] = new ExtensionException(730 'Illegal property name "' . $propertyName . '" of ' . $domainObject->getName() . '.' . LF .731 'Please use lowerCamelCase, no spaces or underscores.',732 self::ERROR_PROPERTY_ILLEGAL_CHARACTER733 );734 }735 $firstChar = $propertyName{0};736 if (strtoupper($firstChar) == $firstChar) {737 $this->validationResult['errors'][] = new ExtensionException(738 'Illegal first character of property name "' . $property->getName() . '" of domain object "' .739 $domainObject->getName() . '".' . LF .740 'Please use lowerCamelCase.',741 self::ERROR_PROPERTY_UPPER_FIRST_CHARACTER742 );743 }744 if (ValidationService::isReservedTYPO3Word($propertyName)) {745 $this->validationResult['warnings'][] = new ExtensionException(746 'The name of property "' . $propertyName . '" in Model "' . $domainObject->getName() .747 '" will result in a TYPO3 specific column name.' . LF .748 ' This might result in unexpected behaviour. If you didn\'t choose that name by purpose' . LF .749 ' it is recommended to use another name',750 self::ERROR_PROPERTY_RESERVED_WORD751 );752 }753 if (ValidationService::isReservedMYSQLWord($propertyName)) {754 $this->validationResult['warnings'][] = new ExtensionException(755 'Property "' . $propertyName . '" in Model "' . $domainObject->getName() . '".',756 self::ERROR_PROPERTY_RESERVED_SQL_WORD757 );758 }759 // Check for duplicate property names760 if (in_array($propertyName, $propertyNames)) {761 $this->validationResult['errors'][] = new ExtensionException(762 'Property "' . $property->getName() . '" of ' . $domainObject->getName() . ' exists twice.',763 self::ERROR_PROPERTY_DUPLICATE764 );765 }766 $propertyNames[] = $propertyName;767 if ($property instanceof AbstractRelation) {768 if (!$property->getForeignModel() && $property->getForeignClassName()) {769 if (!class_exists($property->getForeignClassName())) {770 $this->validationResult['errors'][] = new ExtensionException(771 'Related class not loadable: "' . $property->getForeignClassName() . '" configured in relation "' . $property->getName() . '".',772 self::ERROR_MAPPING_NO_FOREIGNCLASS773 );774 }775 }776 if ($property->getForeignModel() && ($property->getForeignModel()->getFullQualifiedClassName() != $property->getForeignClassName())) {777 $this->validationResult['errors'][] = new ExtensionException(778 'Relation "' . $property->getName() . '" in model "' . $domainObject->getName() .779 '" has a external class relation and a wire to ' . $property->getForeignModel()->getName(),780 self::ERROR_MAPPING_WIRE_AND_FOREIGNCLASS781 );782 }783 }784 }785 }786 /**787 * validates a plugin key788 * @param string $key789 * @return bool true if valid790 */791 private static function validatePluginKey($key)792 {793 return preg_match('/^[a-zA-Z0-9_\-]*$/', $key);...
item.clean.inc
Source:item.clean.inc
...3 $ids = array_keys(Model::all());4 S('log')->debug('INVALID MODELS :');5 foreach ($dbo->getTables() as $table) {6 if (!$table->hasField('model_id')) continue ;7 if (in_array($table->getName(), array(T('node'), T('tree')))) continue ;8 $rs = $dbo->query('SELECT model_id'9 .' FROM '.$table->getName()10 .' WHERE model_id NOT IN ([ids])'11 . ' AND model_id>0'12 .' GROUP BY model_id',13 array('[ids]' => $ids));14 $set = $rs->asSet();15 if (empty($set)) continue ;16 $n = $dbo->exec('DELETE FROM '.$table->getName()17 . ' WHERE model_id IN ([set])',18 array('[set]' => $set));19 S('log')->debug(' - ('.$n.') deletions - model', $table->getName());20 $table->optimize();21 }22 $ids = array();23 foreach (Extension::all() as $extension) {24 $ids[] = $extension['id'];25 }26 foreach ($dbo->getTables() as $table) {27 if (!$table->hasField('extension_id')) continue ;28 $rs = $dbo->query('SELECT extension_id'29 .' FROM '.$table->getName()30 .' WHERE extension_id NOT IN ([ids])'31 . ' AND extension_id>0'32 .' GROUP BY extension_id',33 array('[ids]' => $ids));34 $set = $rs->asSet();35 if (empty($set)) continue ;36 $n = $dbo->exec('DELETE FROM '.$table->getName()37 . ' WHERE extension_id IN ([set])',38 array('[set]' => $set));39 S('log')->debug('- ('.$n.') deletions - extension', $table->getName());40 $table->optimize();41 }42 if ($req->full != 'yes') return ;43 S('log')->debug('INVALID RECORDS :');44 $tables = array_merge(P('item_tables'));45 foreach ($tables as $table) {46 $table = new Table($table); // ML47 $field_model = 'model_id';48 $field_record = 'record_id';49 if ($table->getName() == Meta::TABLE) {50 $field_model = Meta::FIELD_MODEL;51 $field_record = Meta::FIELD_RECORD;52 }53 $models = $dbo->asSet('SELECT DISTINCT '.$field_model54 .' FROM '.$table->getName()55 .' WHERE '.$field_model.'>0');56 if (count($models) < 1) continue ;57 foreach ($models as $model_id) {58 $model_id = (int) $model_id;59 if (!Model::exists($model_id)) {60 $n = $dbo->exec('DELETE FROM '.$table->getName()61 .' WHERE '.$field_model.'='.$model_id);62 S('log')->debug('- ('.$n.') deletions', $table->getName().' : ('.$model_id.')');63 continue ;64 }65 $rs = $dbo->query('SELECT DISTINCT t.'.$field_record66 .' FROM '.$table->getName().' AS t'67 .' LEFT JOIN '.T($model_id).' AS j'68 . ' ON t.'.$field_record.'=j.id'69 .' AND t.'.$field_model.'='.$model_id70 .' WHERE j.id IS NULL'71 . ' AND t.'.$field_model.'='.$model_id);72 $records = $rs->asSet();73 if (count($records) < 1) continue ;74 $n = $dbo->exec('DELETE FROM '.$table->getName()75 .' WHERE '.$field_model.'='.$model_id76 . ' AND '.$field_record.' IN ('.join(',', $records).')');77 S('log')->debug('- ('.$n.') deletions',78 $table->getName().' : '.Model::name($model_id).' ('.$model_id.')');79 }80 }81 foreach (P('item_tables') as $table) {82 if (!$dbo->hasTable($table, false)) continue ;83 $table = $dbo->getTable($table);84 $table->repair();85 $table->optimize();86 }87}88catch (Exception $e) { $err->add($e); }...
getName
Using AI Code Generation
1$ext = new Extension();2echo $ext->getName();3$ext = new Extension();4echo $ext->getName();5$ext = new Extension();6echo $ext->getName();7$ext = new Extension();8echo $ext->getName();9$ext = new Extension();10echo $ext->getName();11$ext = new Extension();12echo $ext->getName();13$ext = new Extension();14echo $ext->getName();15$ext = new Extension();16echo $ext->getName();17$ext = new Extension();18echo $ext->getName();19$ext = new Extension();20echo $ext->getName();21$ext = new Extension();22echo $ext->getName();23$ext = new Extension();24echo $ext->getName();25$ext = new Extension();26echo $ext->getName();27$ext = new Extension();28echo $ext->getName();29$ext = new Extension();30echo $ext->getName();31$ext = new Extension();32echo $ext->getName();33$ext = new Extension();34echo $ext->getName();
getName
Using AI Code Generation
1$ext = new Extension();2echo $ext->getName();3$ext = new Extension();4echo $ext->getAge();5$ext = new Extension();6echo $ext->getGender();7$ext = new Extension();8echo $ext->getAddress();9$ext = new Extension();10echo $ext->getSalary();11$ext = new Extension();12echo $ext->getPhone();13$ext = new Extension();14echo $ext->getDepartment();15$ext = new Extension();16echo $ext->getJobTitle();
getName
Using AI Code Generation
1$object = new Extension();2$object->getName();3$object = new Extension();4$object->getName();5$object = new Extension();6$object->getName();7$object = new Extension();8$object->getName();9$object = new Extension();10$object->getName();11$object = new Extension();12$object->getName();13$object = new Extension();14$object->getName();15$object = new Extension();16$object->getName();17$object = new Extension();18$object->getName();19$object = new Extension();20$object->getName();21$object = new Extension();22$object->getName();23$object = new Extension();24$object->getName();25$object = new Extension();26$object->getName();27$object = new Extension();28$object->getName();29$object = new Extension();30$object->getName();31$object = new Extension();32$object->getName();33$object = new Extension();34$object->getName();35$object = new Extension();36$object->getName();
getName
Using AI Code Generation
1$ext = new Extension();2echo $ext->getName();3$ext = new Extension();4echo $ext->getName();5$ext = new Extension();6echo $ext->getName();7$ext = new Extension();8echo $ext->getName();9$ext = new Extension();10echo $ext->getName();11$ext = new Extension();12echo $ext->getName();13$ext = new Extension();14echo $ext->getName();15$ext = new Extension();16echo $ext->getName();17$ext = new Extension();18echo $ext->getName();19$ext = new Extension();20echo $ext->getName();21$ext = new Extension();22echo $ext->getName();23$ext = new Extension();24echo $ext->getName();25$ext = new Extension();26echo $ext->getName();27$ext = new Extension();28echo $ext->getName();29$ext = new Extension();30echo $ext->getName();31$ext = new Extension();32echo $ext->getName();33$ext = new Extension();34echo $ext->getName();35$ext = new Extension();36echo $ext->getName();37$ext = new Extension();38echo $ext->getName();39$ext = new Extension();40echo $ext->getName();41$ext = new Extension();42echo $ext->getName();43$ext = new Extension();44echo $ext->getName();45$ext = new Extension();46echo $ext->getName();47$ext = new Extension();48echo $ext->getName();49$ext = new Extension();
getName
Using AI Code Generation
1$ext = new Extension();2echo $ext->getName();3$ext = new Extension();4echo $ext->getExtensionName();5Method overloading is the process of creating multiple methods with the same name but different signatures. The method overloading is not possible in PHP because PHP does not support the method overloading. But PHP provides a magic method named __call() which can be used to achieve the method overloading. The __call() method is called when the user tries to access a method which is not defined in the class. The __call() method accepts two parameters: name of the method and the list of arguments passed to the method. The __call() method is declared as follows:6public function __call($name, $arguments)7{8}9$ext = new Extension();10echo $ext->getExtensionName();11$ext = new Extension();12echo $ext->getName();13In the above example, the Extension class does not have the getName() method. But the __call() method is defined in the Extension class. The __call() method is used to create the getName() method. The __call() method accepts two parameters: name of the method and the list of arguments passed to the method. The $name parameter contains the name of the method which is not defined in the class. The $arguments parameter contains the list of arguments passed to the method. The __call() method can be used to create a method with the same name as
getName
Using AI Code Generation
1echo $obj->getName();2echo $obj->getName();3echo $obj->getName();4class ExtensionClass {5 public function getName() {6 return 'Hello World';7 }8}9class ExtensionClass {10 public function getName() {11 return 'Hello World';12 }13}14class ExtensionClass {15 public function getName() {16 return 'Hello World';17 }18}
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Execute automation tests with getName on a cloud-based Grid of 3000+ real browsers and operating systems for both web and mobile applications.
Test now for FreeGet 100 minutes of automation test minutes FREE!!