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 asgetName
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!!
