teppo Posted November 4, 2012 Share Posted November 4, 2012 I'm having a minor nervous breakdown here, so I'd appreciate if someone could tell me exactly what it is that I'm doing wrong. I've got two modules that need each other to work properly. What I'm trying to achieve is that when user installs one of these modules, it automagically installs other module. Also when user uninstalls one of them, other one is also uninstalled. My question is if there's any way to have two modules which a) install and b) uninstall each other automatically? I did try setting up some hand crafted install/uninstall magic, but results ranged from bad to worse, especially regarding automatic uninstallation. Anyway, since ProcessWire these days manages automatic installations / uninstallations itself, that's what I've been mostly focusing. Results, as you can see below, haven't so far been that great. (Sorry for very long post -- I tried to keep it simple, but there were quite a few things to mention and I didn't want to accidentally leave anything important out.) First part, installation, was easy to setup using AutoInstall logic and following settings: A: 'installs' => 'B' B: 'requires' => 'A' This way module B cannot be installed alone, user has to install module A first. When she installs A, B is installed right away and everything is cool so far. What I can't seem to get working is the AutoUninstall part. If user uninstalls A, B is uninstalled too, but things get complicated when she suddenly decides uninstall B first. That way module B is uninstalled but A stays intact, which is not cool at all. Seemingly there's nothing I can do to stop that either. A: 'installs' => 'B', 'requires' => 'B' B: 'requires' => 'A' As you can see above, I tried to solve this by making module A require module B, which makes it impossible to uninstall B first, but that also seems to render AutoInstall useless: while uninstalling module A an error pops out: "Module is required by other modules that must be uninstalled first." After that module A is uninstalled but module B left intact. Bugger. A: 'requires' => 'A', 'installs' => 'B' B: 'requires' => 'A', 'installs' => 'A' My next experiment was telling module B to install module A (and thus also uninstall it) which actually seemed to work -- but with the slight setback that it also caused a loop which ends with PHP timeouting. After timeout both modules are uninstalled, but that's not exactly the way I'd like it to happen. A: 'installs' => 'B' B: 'installs' => 'A' At my final moment of desperation I removed requires from both modules and instead told them to just install each other. Which, naturally, only made things worse; with that setting neither module (no matter how much they claim that "This will also uninstall other modules - A" etc.) can uninstall the other. No errors, nothing. Other module just sits there like nothing happened. I've banged my head on wall with this for way too long already, so I'd appreciate if someone could point me to the right direction. And if what I'm trying to achieve isn't possible with automatic installs / uninstalls, that's also very nice to know. Link to comment Share on other sites More sharing options...
ryan Posted November 4, 2012 Share Posted November 4, 2012 I'm at gym reading tweets between sets so will read/reply better later. But have you looked at the LanguageSupport module that installs/uninstalls its own related modules? 2 Link to comment Share on other sites More sharing options...
teppo Posted November 4, 2012 Author Share Posted November 4, 2012 First of all, can't help admiring your attitude Based on very quick look at the code, LanguageSupport seems to use external installer / uninstaller script to manage dependencies. This is probably something I'll have to take a closer look at tomorrow (11 pm here, seen way too many lines of code for one day already) but according to (equally quick) test it doesn't seem to solve my problem straight away: LanguageSupport installs ProcessLanguage and ProcessLanguageTranslator, both of which are uninstalled with LanguageSupport itself, but I can still remove either one of those latter modules without affecting ProcessLanguage if I so decide. Not sure if that's a problem for LanguageSupport (possibly not, don't really know it's inner workings well enough to say) but it's essentially same behaviour I'm experiencing with my modules (in which case it is a problem.) Link to comment Share on other sites More sharing options...
ryan Posted November 5, 2012 Share Posted November 5, 2012 A: 'installs' => 'B'B: 'requires' => 'A' This one is correct, if I'm understanding what you are trying to do correctly. What I can't seem to get working is the AutoUninstall part. If user uninstalls A, B is uninstalled too, but things get complicated when she suddenly decides uninstall B first. That way module B is uninstalled but A stays intact, which is not cool at all. Seemingly there's nothing I can do to stop that either. If you go and uninstall module B, that is actually okay -- it won't stay uninstalled for long. Whenever you request a module via $modules->get('module name'); it goes ahead and re-installs it (if it's not installed). Here is the key: If module A installs module B and actually uses it for something or another, then module A will continue to work because module B will be installed again as soon as module A executes. This behavior is part of this dependency ecosystem. A: 'installs' => 'B', 'requires' => 'B'B: 'requires' => 'A' If module A requires module B, that means module B must be installed before it will let you install module A. In the above, you've got both modules requiring each other, which would prevent installation of either. A: 'requires' => 'A', 'installs' => 'B'B: 'requires' => 'A', 'installs' => 'A' This is a circular reference. I'm not surprised it timed out. Maybe I should account for that situation, but this is the first I've seen someone making a module require itself. A: 'installs' => 'B'B: 'installs' => 'A' This also seems like another kind of circular reference where the behavior would be undefined. If I'm understanding all correctly, I'm guessing you would suggest this: If module A installs module B, then module B should not be un-installable except by module A? I think this probably makes sense. Currently it does not do that, but I don't see any drawbacks in implementing that behavior. Link to comment Share on other sites More sharing options...
teppo Posted November 5, 2012 Author Share Posted November 5, 2012 If you go and uninstall module B, that is actually okay -- it won't stay uninstalled for long. Whenever you request a module via $modules->get('module name'); it goes ahead and re-installs it (if it's not installed). Didn't realize that. That at least partly solves the problem, though I'd imagine that this could cause some confusion in certain rare cases when uninstalled module is suddenly installed again. Not sure if that's such a big deal, just thinking out loud. This is a circular reference. I'm not surprised it timed out. Maybe I should account for that situation, but this is the first I've seen someone making a module require itself. Cough. Yeah. Sorry for that, it was a typo -- it was really late when I wrote that post after all. What I meant was that A requires and installs B, B requires and installs A.. If I'm understanding all correctly, I'm guessing you would suggest this: If module A installs module B, then module B should not be un-installable except by module A? I think this probably makes sense. Currently it does not do that, but I don't see any drawbacks in implementing that behavior. Even though my post was pretty confusing, you've understood it perfectly. That's exactly what I was going after. 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