Guide to Standardized Hooks - Hook Action Code

Introduction

You can create hook action code in a custom Perl module or as an executable script. Scripts may use any scripting language that the Linux shell can execute. 

  • Hook action code file and subroutine names are arbitrary. However, the system references these names later, when you register your code.
  • Make certain that you save hook action code in the appropriate location on the cPanel & WHM server:
    • Install hook action code modules to the correct directory for your Perl environment.
    • Save hook action scripts in the /usr/local/cpanel/3rdparty/bin directory. Scripts must haveroot:root ownership and 755 permissions.

Note:

For detailed steps to create a hook action code Perl module, read our Create a Standardized Hook tutorial. 

Basic usage

Note:

Perl Module

We recommend that you use the following boilerplate for hook action code Perl modules:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# Package this module.
package MyApp::WHM;
   
# Return errors if Perl experiences problems.
use strict;
use warnings;
     
# Properly decode JSON.
use JSON;
   
# Embed hook attributes alongside the action code.
sub describe {
    my $my_add = {
        'category' => 'Whostmgr',
        'event'    => 'Accounts::Create',
        'stage'    => 'post',
        'hook'     => 'MyApp::WHM::add',
        'exectype' => 'module',
    };
  
    return $my_add ];
}
  
sub add {
    # Get the data that the system passes to the hook.
    my $context$data ) = @_;               
  
    # Set success and failure messages.
    my $result  = 0;                             # This boolean value is set to fail.   
    my $message 'This is an error message.';   # This string is a reason for $result.
     
    # Insert your actions here.
  
    # Return the hook's result and message.
    return $result$message;
}
  
1;


Perl Script

#!/usr/local/cpanel/3rdparty/bin/perl
  
# Return errors if Perl experiences problems.
use strict;
use warnings;
  
# Use objects to handle input.
use IO::Select;
  
# Properly decode JSON.
use JSON::Syck;
 
# Get decoded input.
my $input = get_passed_data();
 
# Declare return variables and set their values.
my $result_result$result_message ) = do_something($input);
 
# Return the return variables and exit.
print "$result_result $result_message";
exit;
 
# Perform the hook's action.
sub do_something {
    # Get the input data.
    my ($input) = @_;
  
    # Set success and failure messages.
    my $result  = 0;                             # This boolean value is set to fail.  
    my $message 'This is an error message.';   # This string is a reason for $result.
 
    # Insert your actions here.
  
    # Return the hook result and message.
    return $result$message;
}
 
# Process data from STDIN.
sub get_passed_data {
    # Declare input variables.
    my $raw_data   '';
    my $input_data = {};
  
    # Set up an input object.
    my $selects    = IO::Select->new();
  
    # Get input from STDIN.
    $selects->add( \*STDIN );
  
    # Process the raw output, and JSON-decode.
    if $selects->can_read(.1) ) {
        while (<STDIN>) {
            $raw_data .= $_;
        }
        $input_data = JSON::Syck::Load($raw_data);
    }
  
    # Return the output.
    return $input_data;
}

PHP Script 

#!/usr/local/cpanel/3rdparty/bin/php -q
 
<?php
 
// Get decoded input.
$input = get_passed_data();
 
// Declare return variables and set their values.
list($result_result$result_message) = do_something($input);
 
// Return the return variables.
echo "$result_result $result_message";
 
// Perform the hook's action, using the decoded input.
function do_something($input array()) {
    // Insert your actions here.
  
    // Set success and failure messages.
    $result "0";                            // This boolean value is set to fail.    
    $message "This is an error message.";   // This string is a reason for $result.
  
    // Return the hook result and message.
    return array($result$message);
}
 
// Process data from STDIN.
function get_passed_data() {
  
    // Get input from STDIN.
    $raw_data;
    $stdin_fh fopen('php://stdin''r');
    if is_resource($stdin_fh) ) {
        stream_set_blocking($stdin_fh, 0);
        while ( ($line fgets$stdin_fh, 1024 )) !== false ) {
            $raw_data .= trim($line);
        }
        fclose($stdin_fh);
    }
  
    // Process and JSON-decode the raw output.
    if ($raw_data) {
        $input_data = json_decode($raw_data, true);
    else {
        $input_data array('context'=>array(),'data'=>array(), 'hook'=>array());
    }
  
    // Return the output.
    return $input_data;
}
?>

Package the module.

1
2
# Package this module.
package MyApp::WHM;

This declaration instructs Perl to treat all of the module's functions as part of theMyApp::WHM module.

  • When you use the manage_hooks utility to register your hook, you will use this module name as your hook action code's location.
  • For more information, read perldoc.perl.org's package documentation.

Set the strict pragma and use warnings.

4
5
6
# Return errors if Perl experiences problems.
use strict;
use warnings;

These declarations instruct Perl to return errors if the file contains potentially-unsafe code.

Note:

You can omit the warnings declaration in production code, but we stronglyrecommend that you use it during development. 

Properly decode JSON.

8
9
# Properly decode JSON.
use JSON;

The JSON module properly encodes and decodes JSON.

Important:

Hook action code must read the entire @_ stream until end of line (EOL), andmust treat it as a JSON-encoded data structure. 

Use the describe() method to embed hook attributes.

11
12
13
14
15
16
17
18
19
20
21
22
# Embed hook attributes alongside the action code.
sub describe {
    my $my_add = {
        'category' => 'Whostmgr',
        'event'    => 'Accounts::Create',
        'stage'    => 'post',
        'hook'     => 'MyApp::WHM::add',
        'exectype' => 'module',
    };
   
    return $my_add ];
}

The describe() method embeds hook attributes in your hook action code.

  • We strongly recommend that you use this method, because it drastically simplifies the manage_hooks hook registration process.
  • For more information, read our The describe() Method documentation.

Write the hook subroutine.

The hook subroutine should contain all of the actions that your hook will perform.

  • We recommend that you use lowercase function names.
  • If your function name includes multiple words, separate each word with an underscore (_) for readability. 
  • Do not begin functions with an underscore (_).
  • For more information about subroutines in Perl, read perldoc.perl.org's perlsub documentation.

Get data from @_

25
26
# Get the data that the system passes to the hook.
my $context$data ) = @_

Declare the  $context and $data variables and assign them the appropriate values from  @_ . 

Remember:

Hook action code that exists in a script (not a module) must read two full lines from the STDIN stream until end of line (EOL), and it must treat these lines as JSON-encoded data structures. After the system decodes the JSON string, the native data structure is a hash.

 Whenever an event triggers hook action code, the system passes in the following input parameters:

Input

Type

Description

Possible values

Example

 context 

string

 The hookable event and its category. 

A hookable event category, two colons (:), and the event name.

 Passwd::ChangePasswd 

data

 hash reference 

The event's information.

A hash reference to a hash ofkey=value pairs.

Note:

 Some events do not provide data. For these events, thedataparameter is undefined. 

key=value

 

Set success and failure messages.

28
29
30
# Set success and failure messages.
my $result  = 0;                             # This boolean value is set to fail.  
my $message 'This is an error message.';   # This string is a reason for $result. 

Declare the  $result and $message variables and assign them values. You can manipulate these values in your custom actions, to return helpful output.

We recommend that you write hook action code to return the following output:

Input

Type

Description

Possible values

Example

result

 boolean 

Required

Whether the action succeeded.

Important:

  • The only meaningfulreturn values in Perl are 1 (for success) and 0 (for failure).
  • While Perl allows bare return values, we do notrecommend that you use them. In some circumstances, the system may misinterpret barereturn values as true. 
  • 1 — Success.
  • 0 — Failure.
 

1

 message 

string

A message of success, or an error message.

Note:

To block the hook event on failure, you must set the blockable value to1 in the describe()method and include the following line in your code:

die("$message");

  • A confirmation message. 
  • A reason for failure.

 This is an error message. 

 

Return the hook's result.

34
35
# Return the hook's result and message.
return $result$message

After your subroutine performs the desired actions, return the $result and $messagevalues. Hook action code's primary return value must be a single-line print statement to STDOUT.

  • 0 Users Found This Useful
Was this answer helpful?

Related Articles

The cPanel Interface

For  cPanel  &  WHM  version  58 Overview The cPanel interface is...

User Preferences

For cPanel & WHM version 58 Overview This document outlines how to access your cPanel...

Manage External Authentications

For cPanel & WHM version 58 Overview Manage credentials Additional documentation...

What is cPanelID?

In This Article:  Overview ServicesHow to get a cPanelID cPanelID External...

Guide to cPanel Interface Customization - cPanel Style Development

Introduction You can develop custom styles that modify the appearance of the cPanel interface....