bora Posted April 24, 2016 Share Posted April 24, 2016 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 https://gist.github.com/borantula/e41c4b6ba36f78b1110d400a16754691 2 Link to comment Share on other sites More sharing options...
LostKobrakai Posted April 24, 2016 Share Posted April 24, 2016 You probably had the same problem as described here: https://processwire.com/talk/topic/13101-files-are-compiled-twice-translatable-strings-are-not-translated/ 1 Link to comment Share on other sites More sharing options...
bora Posted April 24, 2016 Author Share Posted April 24, 2016 You probably had the same problem as described here: https://processwire.com/talk/topic/13101-files-are-compiled-twice-translatable-strings-are-not-translated/ 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 More sharing options...
tpr Posted April 24, 2016 Share Posted April 24, 2016 I would probably solve this using a search & replace on files. 1 Link to comment Share on other sites More sharing options...
ryan Posted April 24, 2016 Share Posted April 24, 2016 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. 3 Link to comment Share on other sites More sharing options...
bora Posted April 25, 2016 Author Share Posted April 25, 2016 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 More sharing options...
szabesz Posted April 25, 2016 Share Posted April 25, 2016 ... 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 More sharing options...
gebeer Posted January 18, 2017 Share Posted January 18, 2017 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 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 More sharing options...
Mike Rockett Posted January 18, 2017 Share Posted January 18, 2017 @gebeer - I would be inclined to make that compatible with namespaces being on the third line as well - not everyone keeps it right at the top next to the open-tag. Link to comment Share on other sites More sharing options...
gebeer Posted January 18, 2017 Share Posted January 18, 2017 @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 1 Link to comment Share on other sites More sharing options...
Mike Rockett Posted January 18, 2017 Share Posted January 18, 2017 @gebeer - Works perfectly. Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now