wohali Posted October 30, 2017 Posted October 30, 2017 Is there a(n IPS-approved) way to programmatically create a code hook? I'm developing an application that I'd like to optionally add a hook to a 3rd party app, if installed. I can't work out how I can achieve this. Normally I would use the ACP development console to add a hook, but if the 3rd party app isn't installed, I can't add a code hook to its class, because the ACP will tell me that class doesn't exist. And though I haven't tried it, I assume that if I do install the 3rd party app, build my code hook, compile and download the app, then try and install it on an IPS4 install that doesn't have that 3rd party app installed, the install will fail because the class doesn't exist there, either. I know I can do something like if ( array_key_exists( 'foo', \IPS\Application::applications() ) {...} If there is an acceptable way to programmatically create a code hook, I can add something like this to bracket my hook install inside of upgrade.php or an ACP settings page.
wohali Posted October 30, 2017 Author Posted October 30, 2017 Following up to my own question, I've read system/Application/Application.php and it looks like I could do something like the following: if ( array_key_exists( 'foo', \IPS\Application::applications() ) { // TODO: check if hook already installed with a clever \IPS\Db::i()->select() and uninstall/replace if not latest ver foreach( json_decode( file_get_contents( "calculated/path/to/my/special/hooks.json" ), TRUE ) as $filename => $data ) { \IPS\Db::i()->insert( 'core_hooks', array( 'app' => 'my_app_name', 'type' => $data['type'], 'class' => $data['class'], 'filename' => $filename ) ); if ( $data['type'] === 'S' ) { $templatesToRecompile[ $data['class'] ] = $data['class']; } } \IPS\Plugin\Hook::writeDataFile(); foreach ( $templatesToRecompile as $k ) { $exploded = explode( '_', $k ); \IPS\Theme::deleteCompiledTemplate( $exploded[1], $exploded[2], $exploded[3] ); } } In short, almost a direct cut & paste of installHooks(). The only other thing I can think of that would be cleaner is to ship 2 apps, one with the base addon and one as a special "install me only if you also have this specific 3rd party app." Given how much cut & paste the above is, and how I might have to chase after changes in the future, I'm leaning this direction...but I'm hoping to hear from IPS on this one first.
teraßyte Posted October 30, 2017 Posted October 30, 2017 You could simply add the hook in your own application and overload the class of the other one. As long as the other application is not installed the hook will simply not be called/executed at all. An hook can work on another 3rd party application from your own application, there is no requirement to have the hook in the app it runs for. Unless I am misunderstanding what you want to do...
wohali Posted October 30, 2017 Author Posted October 30, 2017 Right, the problem is the adding of the hook itself during IPS's app installation process. I don't know if the app installation process will fail if that class doesn't exist. I guess I should just test it, but it's a huge pain for me to do so, since both my live and my test sites have that 3rd party app installed. :/
wohali Posted October 31, 2017 Author Posted October 31, 2017 OK, I decided to Try It And See by making two trivial apps, one that hooked into and extended the other. Thankfully, my assumption was wrong. So, for future reference: Have the app you wish to hook installed on your dev instance. Make the Class Hook in the usual way per the ACP, extending the other app's class Develop and download your app as usual. You can install this app on systems that don't have the class you want to extend without making the installer complain. Useful! Thanks for the help.
Recommended Posts
Archived
This topic is now archived and is closed to further replies.