Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Namespace duplication in files & directories and include error: Cannot find <TableName>TableMap files #1036

Open
bogdandynamic opened this issue Sep 13, 2016 · 2 comments

Comments

@bogdandynamic
Copy link

The scenario: PgSql database, PHP 5.6, propel 2 installed via composer
Step 1: Generating schema.xml file from existing PgSql database with namespace parameter "PROJECT\Database" (the namespace appears in the database tag and also in each of the table tags inside it). All OK until now.
Step 2: When generating class files from the schema.xml (calling from the ROOT_PROJECT_DIRECTORY with the command vendor/bin/propel model:build --platform=pgsql --output-dir="Database/" --schema-dir="Database/Config/") it generates all the files in ROOT_PROJECT_DIRECTORY/Database/PROJECT/Database directory when the intended directory should be (from my perspective) ROOT_PROJECT_DIRECTORY/Database (as specified from the --output-dir parameter). This was fixed by removing the namespace from the database tag in the schema.xml file. I tried keeping the namespace from the database tag and removing the namespace from the table tags but that screws the namespaces inside the generated files.
The directory structure looks like this after doing the above:

  • ROOT_PROJECT_DIRECTORY
    • Database
      • Base
      • Config (where the schema.xml file is located)
      • Map

Step 3: Trying to run an example to echo a count() from one table but PHP cannot find the following file: ROOT_PROJECT_DIRECTORY\DatabaseTableMap.php file, that is located in ROOT_PROJECT_DIRECTORY\Database\Map directory.
After doing some debugging I've found the Propel\Runtime\Map\DatabaseMap.php file where there the getTableByPhpName function resides (line 181). The workaround for me was switching the whole if (class_exists($tmClass = $phpName . 'TableMap')) with if (class_exists($tmClass = substr_replace($phpName, '\\Map\\', strrpos($phpName, '\\'), 1) . 'TableMap') || class_exists($tmClass = '\\Map\\' .$phpName . 'TableMap'))

One more thing to take into consideration is the fact that PgSql can have table/column/etc. names in CamelCase/camelCase style (like I like to name them). When generating the schema.xml from an existing database, the phpName parameter for every table/column was is the UNDERSCORE style and did not found any parameter in the cli command or configuration parameter in the xml/yaml/php configuration file to specify the style for the phpName. I had to change the default UNDERSCORE style throughout the code into NOCHANGE. If there is a configuration parameter or something equivalent please disregard this last paragraph.

@bogdandynamic
Copy link
Author

bogdandynamic commented Sep 14, 2016

On further debugging I discovered that if the --namespace parameter in the propel database:reverse command is a fully qualified namespace (starts with \), the namespaces declaration inside the files generated with the propel model:build command are as expected. I believe that should be mentioned in the documentation.

The problem seems to be in Propel\Generator\Manager\ModelManager.php file in the doBuild function. The $path variable will be in the form NAMESPACE\[EMPTY|BASE|MAP\]TableName.php and later on you do $file = new \SplFileInfo($this->getWorkingDirectory() . DIRECTORY_SEPARATOR . $path);.
In many cases the working directory will be the same as some part or the whole NAMESPACE provided before. I'll try and provide a fix.

@bogdandynamic bogdandynamic changed the title Cannot find <TableName>TableMap files Namespace duplication in files & directories and include error: Cannot find <TableName>TableMap files Sep 14, 2016
@bogdandynamic
Copy link
Author

bogdandynamic commented Sep 14, 2016

Managed to fix the issue in my case by adding the following code in the doBuildfunction in Propel\Generator\Manager\ModelManager.php.

       $path = $builder->getClassFilePath();
        // ADDED CODE
        $databaseNamespace = $builder->getDatabase()->getNamespace();
        if($databaseNamespace[0] == '\\'){
            $databaseNamespace = substr($databaseNamespace, 1);
        }
        $namespaceComponents = explode('\\', $databaseNamespace);
        foreach($namespaceComponents as $component){
            $pos = strpos($path, $component);
            if($pos !== false){
                $path = substr($path, $pos + strlen($component));
                if($path[0] == '\\' || $path[0] == '/'){
                    $path = substr($path, 1);
                }
            }
        }
        // END OF ADDED CODE
        $file = new \SplFileInfo($this->getWorkingDirectory() . DIRECTORY_SEPARATOR . $path);
        $this->filesystem->mkdir($file->getPath());

Hope this helps someone.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant