Jump to content

Processwire 2 to 3 namespace migration script


bora
 Share

Recommended Posts

Hello everyone,

Last night as a "saturday night shitty weather stay at home" project I attempted to migrate a project that was on PW 2.7.x to PW 3.x 

I use a lot of partials on the project so I have around 200 php files that needs to be namespaced. Compiler was giving me trouble with "Call undefined function" errors.

Being the lazy developer I attempted to wrote a script after getting bored over pasting  the namespace Processwire; line into around 10 files.

Below you can find the script, that is very basically adds <?php namespace Processwire;?> as the first line of every .php and .module file in the given directory and shows you the results. Of course it checks for namespace Processwire first :)

By default it assumes ./site/templates folder but I tried it with a module which is giving errors due to namespaces and worked fine.

Be careful and remember to take backups first :D

https://gist.github.com/borantula/e41c4b6ba36f78b1110d400a16754691

  • Like 2
Link to comment
Share on other sites

Yes, I use wireRenderFile method extensively. Now I tried again by changing all calls to wireRenderFile function to absolute from the wrapper function I use. I only put namespace on root folder of templates. But even though I use full paths on wireRenderFile, the .php files in templates/partials still throws errors like 

Fatal error: Call to undefined function getCatalogues() in /var/www/dev.com/pw3/site/templates/partials/main.php on line 9

(it's defined in _func.php)

Link to comment
Share on other sites

Yes, I use wireRenderFile method extensively. Now I tried again by changing all calls to wireRenderFile function to absolute from the wrapper function I use. I only put namespace on root folder of templates. But even though I use full paths on wireRenderFile, the .php files in templates/partials still throws errors like 
Fatal error: Call to undefined function getCatalogues() in /var/www/dev.com/pw3/site/templates/partials/main.php on line 9
(it's defined in _func.php)
I actually don't think this is a matter of file paths. That error points to one file (like _func.php) having a namespace, and another file (like main.php) not having a namespace (or not referring to the function in the namespace that it exists). If you are letting PW decide whether to compile a file based on whether it has a namespace or not, then you've got to take those same considerations for any files it might include(). A file that doesn't get compiled isn't going to have files include()'d from it compiled either. So it sounds like you probably do have a namespace defined in your _func.php file, but not in your main.php file (or the opposite). For your case, since you are adding a namespace to the to of all your .php files, I'd suggest disabling the compiler by setting $config->templateCompile=false; in your /site/config.php. 
  • Like 3
Link to comment
Share on other sites

I actually don't think this is a matter of file paths. That error points to one file (like _func.php) having a namespace, and another file (like main.php) not having a namespace (or not referring to the function in the namespace that it exists). If you are letting PW decide whether to compile a file based on whether it has a namespace or not, then you've got to take those same considerations for any files it might include(). A file that doesn't get compiled isn't going to have files include()'d from it compiled either. So it sounds like you probably do have a namespace defined in your _func.php file, but not in your main.php file (or the opposite). For your case, since you are adding a namespace to the to of all your .php files, I'd suggest disabling the compiler by setting $config->templateCompile=false; in your /site/config.php. 

That was actually what I did, disable templateCompile from config.php after running this script. Added this recommendation to gist as well to help anyone willing to try it.

Adding namespace to all files and disabling templateCompile is, as far as I understand, is the cleanest state for PW3.

By the way FileCompiler worked for modules flawlessly, except two small exceptions (one was my fault one was 3rd party module). This week I'll test further before migrating to PW3 on production as well. So far on my local copy I enjoy the perks of PW3 already :)

On the other hand, adding namespace to every little view partial doesn't look like very ideal and practical. I will look into other possible ways of using partials instead of wireRenderFile. 

Error generally occured due to using global functions like wire() or functions from _func.php on non-namespaced files. Out of habit from Laravel, CakePHP etc. I assumed that global functions would continue working without a namespace but then I realized I should be thinking everything within Processwire.

Link to comment
Share on other sites

... Adding namespace to all files and disabling templateCompile is, as far as I understand, is the cleanest state for PW3...

Considering the new "File Compiler modules" feature of PW, it actually depends on your requirements:

https://processwire.com/blog/posts/processwire-3.0-alpha-2-and-2.6.22-rc1/#file-compiler-modules

However, most of us will rarely use this tool, I suppose...

Link to comment
Share on other sites

  • 8 months later...
On 4/24/2016 at 11:34 PM, tpr said:

I would probably solve this using a search & replace on files.

That is what I did.

You can get every file in directory templates that ends in .php. Then look if the file starts on the first line with <?php. If <?php is not followed by namespace ProcessWire, it will be replaced.

The regex expression for the find operation

\A^<\?php(?!\ namespace\ ProcessWire;)

My Sublime Find&Replace panel looks like this

2017-01-18 11:13:49.png

You can adjust file paths and endings to catch other files in other directories (e.g. modules) as well.

Should work in other editors that support regex search/replace across files, too.

Link to comment
Share on other sites

@Mike Rockett Thanks for the pointer. Didn't think about it. I was looking at the default site profile template files and they all have it in the first line.

My post was meant as an example on how you can approach the problem with search/replace and regex. People can adjust the regex to fit their needs.

However, I put together a new regex, that searches for <?php in the first line of a document which is not followed by any number of spaces, tabs or newlines and 'namespace ProcessWire;'.

You can see it in action here.  remove the first line and then add any number of new lines between '<?php' and 'namespace ProcessWire' to see that it works. It only picks up <?php  in the first line of the document.

Here it is for convenience

(^<\?php(?![ \t\n]*namespace ProcessWire;)[ \t]*)/g

 

  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...