Jump to content
hosthuski

Hook that executes shell script and passes variable based on product's service ID

Recommended Posts

Hello all. I am hoping you can help me do what I think should be simple for people who have dealt with hooks already.

I want to do this:

IF a product's ID = x (I imagine this involves getting the product ID from a variable and doing an IF statement in PHP)

THEN 

get the service_domain field (built-in field, not custom field),

run a shell script while passing the domain field as a bash variable to be used within the script's execution.

Why do I want to do this?

This will allow me to begin the process of provisioning maintenance coverage via WP CLI for customers who order a maintenance plan from us.

I'll create an additional 2 hooks -- three total so one for each maintenance plan. If I can get the first hook, i can make the others and likely merge them together. I just need a "template" to follow from someone who understands PHP more than on the surface like I do. This ultimately will chain 3 of my servers together. WHMCS server, our cPanel server, and the maintenance server.

Any help is appreciated. Would anyone be willing to paste in an effective code sample that I can use?

Share this post


Link to post
Share on other sites

When do you want the hook to fire?   Let's say after the server modules does the create:

<?php
add_hook('AfterModuleCreate', 1, function($vars) {
    if (isset($vars['domain']) and !empty($vars['domain']))
    {
        if (function_exists("exec"))
        {
            exec("/path/to/script/shell.sh ".$vars['domain'], $Output, $result_code);
          	// Shell scripts should return "0" when successful and any other number when failed
            if ($result_code === 0)
            {
                // Yay, we are successful, now process output if really wanted
                foreach($Output as $line)
                {
                    if ($line === "some output")
                    {
                        // Run more processing
                    }
                }
            }
            else
            {
                throw new Exception("Uh oh batman, the joker got away");
            }
        }
        else
            throw new Exception("Dude, the security here is nice but we can't do anything");
    }
    else
        throw new Exception("Uh oh, domain isn't given and it should be but it isn't but it reallly should have been!!!");
});

Just note shell_exec, exec, and the other such functions can be disabled for security and so that is the case you would need to have that removed for this to be possible. 

Share this post


Link to post
Share on other sites

Whenever exec or shell\_\exec is used, it should be absolutely ensured that the user input is validated, otherwise this can end problematically. I don't see a big problem with the "domain" parameter, since WHMCS should already validate this value, but it's definitely not wrong to validate the parameters again, just in case. 

In addition to validation, I recommend escaping the arguments via the standard PHP function escapeshellarg.

PS: I had to obfuscate shell\_\exec as otherwise the WHMCS server does block my post.

Share this post


Link to post
Share on other sites

Thank you so much everyone. This is a huge help to get started.

3 hours ago, steven99 said:

When do you want the hook to fire?   Let's say after the server modules does the create:

That would be great but I don't have a module for this. So I'm hoping to avoid using a module by using a hook instead. In this case, the hook would read what the ID of the product is (to match a product in my products list) and check if it = X.

This way when someone buys a specific product (ie: Maintenance) I can run the hook to provision the maintenance. And if it doesn't match a product we want to match, it does nothing.

Share this post


Link to post
Share on other sites
<?php
add_hook('AcceptOrder', 1, function($vars) {
    $serviceid = $vars['serviceid'];
    if (isset($vars['domain']) and !empty($vars['domain']) and isset($vars['serviceid']) and in_array($serviceid, ['10','11','12'], true )  )
    {
        if (function_exists("exec"))
        {
            exec("path/to/bash.sh ".$vars['domain'], $Output, $result_code);
          	// Shell scripts should return "0" when successful and any other number when failed
            if ($result_code === 0)
            {
            exit;
            }
            else
            {
                throw new Exception("Maintenance plan failed to provision automatically. Manual setup required.");
            }
        }
    }
});

Thanks everyone for your help. I've come up with this for my hook code. Does this look like it will be sufficient?

Share this post


Link to post
Share on other sites

You'll want to do a "return true" or "return 'success'" or nothing instead of just "exit" as that will quit WHMCS processes . 

Share this post


Link to post
Share on other sites
15 minutes ago, steven99 said:

You'll want to do a "return true" or "return 'success'" or nothing instead of just "exit" as that will quit WHMCS processes . 

Thanks! Fixed it.

<?php
add_hook('AcceptOrder', 1, function($vars) {
    $serviceid = $vars['serviceid'];
    if (isset($vars['domain']) and !empty($vars['domain']) and isset($vars['serviceid']) and in_array($serviceid, ['10','11','12'], true )  )
    {
        if (function_exists("exec"))
        {
            exec("/path/to/bash.sh ".$vars['domain'], $Output, $result_code);
          	// Shell scripts should return "0" when successful and any other number when failed
            if ($result_code === 0)
            {
            exit;
            }
            return true
            {
                throw new Exception("Maintenance plan failed to provision automatically. Manual setup required.");
            }
        }
    }
});

 

Share this post


Link to post
Share on other sites

Wasn't clear I guess, but you want to replace "exit" with "return true".   Having exit any where in there will cause PHP to exit out and stop whmcs from doing any other actions. 

Share this post


Link to post
Share on other sites
Posted (edited)

oops! I accidentally erased "else" thinking it was "exit." don't worry. you were perfectly clear. it's fixed now. that's embarassing.

<?php
add_hook('AcceptOrder', 1, function($vars) {
    $serviceid = $vars['serviceid'];
    if (isset($vars['domain']) and !empty($vars['domain']) and isset($vars['serviceid']) and in_array($serviceid, ['10','11','12'], true )  )
    {
        if (function_exists("exec"))
        {
            exec("/path/to/bash.sh ".$vars['domain'], $Output, $result_code);
          	// Shell scripts should return "0" when successful and any other number when failed
            if ($result_code === 0)
            {
            return true
            }
            else
            {
                throw new Exception("Maintenance plan failed to provision automatically. Manual setup required.");
            }
        }
    }
});

 

Edited by hosthuski

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Similar Content

    • By Davor
      Hello,
      I have a hook that redirects the Home navigation from Portal home to my Homepage:
      use WHMCS\View\Menu\Item as MenuItem; add_hook('ClientAreaPrimaryNavbar', 1, function (MenuItem $primaryNavbar) { if (!is_null($primaryNavbar->getChild('Home'))) { $primaryNavbar->getChild('Home') ->setURI('../'); } });  
       
      But can't find a hook to change when a user clicks on the Icon in the Header to also change it to homepage and not to the Portal home.
      Been looking for hours now, but no luck.
       
       

    • By MCERENZIA31
      Hello,
      Could you give me all the variables available for a quote.
      I would like to include the price of the quote in my email.
      Thank you
    • By Danse
      Hi, does anyone has a Hook which auto enables the DNS of new Domains in WHMCS? 
      Customers always complaining that DNS Management is missing and i have to switch that on, all the Time. 
      And i wont take this as upselling position. So activate DNS Management in Frontend for "0$" is aswell not suitable for me. 
      It just be there and done 🙂
      Any Suggestions, or Code Templates? 
    • By Dreza
      Hello,
      I created a hook file for the 'OrderPaid' event and it seems like the $vars variable that is being passed to it always comes up empty. Does anyone know why this is happening?
  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use & Guidelines and understand your posts will initially be pre-moderated