From cfdc834a0ecb09a0df2effd066b2be01bce39dd3 Mon Sep 17 00:00:00 2001 From: Andy Rixon Date: Wed, 25 Oct 2023 22:54:42 +0100 Subject: [PATCH] Initial Commit of Module --- .gitignore | 1 + azuracast/azuracast.php | 1069 ++++++++++++++++++++++++++++++ azuracast/hooks.php | 110 +++ azuracast/lib/README.md | 1 + azuracast/logo.png | Bin 0 -> 12464 bytes azuracast/templates/error.tpl | 9 + azuracast/templates/manage.tpl | 48 ++ azuracast/templates/overview.tpl | 288 ++++++++ 8 files changed, 1526 insertions(+) create mode 100644 .gitignore create mode 100644 azuracast/azuracast.php create mode 100644 azuracast/hooks.php create mode 100644 azuracast/lib/README.md create mode 100644 azuracast/logo.png create mode 100644 azuracast/templates/error.tpl create mode 100644 azuracast/templates/manage.tpl create mode 100644 azuracast/templates/overview.tpl diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e43b0f9 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.DS_Store diff --git a/azuracast/azuracast.php b/azuracast/azuracast.php new file mode 100644 index 0000000..df5b21b --- /dev/null +++ b/azuracast/azuracast.php @@ -0,0 +1,1069 @@ + 'AzuraCast', + 'APIVersion' => '1.1', // Use API Version 1.1 + 'RequiresServer' => true, // Set true if module requires a server to work + 'DefaultNonSSLPort' => '', // Default Non-SSL Connection Port + 'DefaultSSLPort' => '', // Default SSL Connection Port + 'ServiceSingleSignOnLabel' => 'Login to AzuraCast', + 'AdminSingleSignOnLabel' => 'Login to AzuraCast', + ); +} + +/** + * Define product configuration options. + * + * The values you return here define the configuration options that are + * presented to a user when configuring a product for use with the module. These + * values are then made available in all module function calls with the key name + * configoptionX - with X being the index number of the field from 1 to 24. + * + * You can specify up to 24 parameters, with field types: + * * text + * * password + * * yesno + * * dropdown + * * radio + * * textarea + * + * Examples of each and their possible configuration parameters are provided in + * this sample function. + * + * @see https://developers.whmcs.com/provisioning-modules/config-options/ + * + * @return array + */ +function azuracast_ConfigOptions() +{ + return array( + // a text field type allows for single line text input + 'Max Listenrs' => array( + 'Type' => 'text', + 'Size' => '25', + 'Default' => '50', + 'Description' => 'Enter the max amount of listeners that this package can have', + ), + // the dropdown field type renders a select menu of options + 'AutoDJ Enabled' => array( + 'Type' => 'dropdown', + 'Options' => array( + 'yes' => 'Yes', + 'no' => 'No', + ), + 'Description' => 'Is AutoDJ enabled for this package', + ), + 'Streamer DJs Enabled' => array( + 'Type' => 'dropdown', + 'Options' => array( + 'yes' => 'Yes', + 'no' => 'No', + ), + 'Description' => 'Is Streamer DJs enabled for this package', + ), + ); +} + +/** + * Provision a new instance of a product/service. + * + * Attempt to provision a new instance of a given product/service. This is + * called any time provisioning is requested inside of WHMCS. Depending upon the + * configuration, this can be any of: + * * When a new order is placed + * * When an invoice for a new order is paid + * * Upon manual request by an admin user + * + * @param array $params common module parameters + * + * @see https://developers.whmcs.com/provisioning-modules/module-parameters/ + * + * @return string "success" or an error message + */ +function azuracast_CreateAccount(array $params) +{ + try { + // Call the service's provisioning function, using the values provided + // by WHMCS in `$params`. + // + // A sample `$params` array may be defined as: + // + // ``` + // array( + // 'domain' => 'The domain of the service to provision', + // 'username' => 'The username to access the new service', + // 'password' => 'The password to access the new service', + // 'configoption1' => 'The amount of disk space to provision', + // 'configoption2' => 'The new services secret key', + // 'configoption3' => 'Whether or not to enable FTP', + // ... + // ) + // ``` + // Gather together all the config stuff we need. + $station_name = $params['customfields']['Station Name']; + $station_url = $params['customfields']['Station URL']; + $station_genre = $params['customfields']['Station Genre']; + $station_desc = $params['customfields']['Station Description']; + $listeners = $params['configoption1']; + $ac_name = $params['clientsdetails']['firstname'].' '.$params['clientsdetails']['lastname']; + $sc_email = rand(10000,99999).'@'.$params['serverhostname']; + $ac_pass = $params['password']; + $ac_now = time(); + $api_key = $params['serverpassword']; + if($params['serversecure']=='on'){ + $secure = 'https://'; + } else { + $secure = 'http://'; + } + if($params['configoption2']=='yes'){ + $autodj = 'liquidsoap'; + } else { + $autodj = 'none'; + } + if($params['configoption3']=='yes'){ + $streamers = 'true'; + } else { + $streamers = 'false'; + } + $api_url = $secure.$params['serverhostname']; + // DEBUG ME + //die($autodj); + + // Let's create the station + $short = str_replace(' ', '_', $station_name); + $short_name = strtolower($short); + $create_url = $api_url.'/api/admin/stations'; + $create_ch = curl_init(); + $create_headers = array( + 'Accept: application/json', + 'Content-Type: application/json', + 'X-API-Key: '.$api_key, + ); + curl_setopt($create_ch, CURLOPT_URL, $create_url); + curl_setopt($create_ch, CURLOPT_HTTPHEADER, $create_headers); + curl_setopt($create_ch, CURLOPT_HEADER, 0); + $create_body = '{ + "id": 0, + "name": "'.$station_name.'", + "short_name": "'.$short_name.'", + "is_enabled": true, + "frontend_type": "shoutcast2", + "frontend_config":{"max_listeners":'.$listeners.'}, + "backend_type": "'.$autodj.'", + "backend_config": [ + "string" + ], + "description": "'.$station_desc.'", + "url": "'.$station_url.'", + "genre": "'.$station_genre.'", + "radio_base_dir": "/var/azuracast/stations/'.$short_name.'", + "enable_requests": false, + "request_delay": 5, + "request_threshold": 15, + "disconnect_deactivate_streamer": 0, + "enable_streamers": '.$streamers.', + "is_streamer_live": false, + "enable_public_page": false, + "enable_on_demand": false, + "enable_on_demand_download": false, + "enable_hls": false, + "api_history_items": 5, + "timezone": "UTC", + "branding_config": [ + "string" + ] + }'; + curl_setopt($create_ch, CURLOPT_POSTFIELDS,$create_body); + curl_setopt($create_ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($create_ch, CURLOPT_TIMEOUT, 30); + $create_json_return = curl_exec($create_ch); + $create_return = json_decode($create_json_return); + if($create_return->{'code'}=='500'||$create_return->{'code'}=='403'||$create_return->{'code'}=='404'){ + die($create_return->{'formatted_message'}); + } else { + $station_id = $create_return->{'id'}; + $params['model']->serviceProperties->save(['Station ID' => $station_id]); + + // Create Permissions + $perm_url = $api_url.'/api/admin/roles'; + $perm_ch = curl_init(); + $perm_headers = array( + 'Accept: application/json', + 'Content-Type: application/json', + 'X-API-Key: '.$api_key, + ); + curl_setopt($perm_ch, CURLOPT_URL, $perm_url); + curl_setopt($perm_ch, CURLOPT_HTTPHEADER, $perm_headers); + curl_setopt($perm_ch, CURLOPT_HEADER, 0); + $perm_body = '{ + "id": 0, + "name": "'.$short_name.'", + "permissions": { + "global": [], + "station": { + "'.$station_id.'": [ + "manage station automation", + "manage station broadcasting", + "manage station media", + "manage station mounts", + "manage station podcasts", + "manage station remotes", + "manage station streamers", + "manage station web hooks", + "view station logs", + "view station management", + "view station reports" + ] + } + } +}'; + curl_setopt($perm_ch, CURLOPT_POSTFIELDS,$perm_body); + curl_setopt($perm_ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($perm_ch, CURLOPT_TIMEOUT, 30); + $perm_json_return = curl_exec($perm_ch); + $perm_return = json_decode($perm_json_return); + if($perm_return->{'code'}=='500'||$perm_return->{'code'}=='403'||$perm_return->{'code'}=='404'){ + die($perm_return->{'formatted_message'}); + } else { + $perm_id = $perm_return->{'id'}; + $perm_name = $perm_return->{'name'}; + // create user now + $user_url = $api_url.'/api/admin/users'; + $user_ch = curl_init(); + $user_headers = array( + 'Accept: application/json', + 'Content-Type: application/json', + 'X-API-Key: '.$api_key, + ); + curl_setopt($user_ch, CURLOPT_URL, $user_url); + curl_setopt($user_ch, CURLOPT_HTTPHEADER, $user_headers); + curl_setopt($user_ch, CURLOPT_HEADER, 0); + $user_body = '{ + "id": 0, + "email": "'.$sc_email.'", + "new_password": "'.$ac_pass.'", + "name": "'.$ac_name.'", + "locale": "en_US", + "show_24_hour_time": true, + "created_at": '.$ac_now.', + "updated_at": '.$ac_now.', + "roles": [ + { +"id": '.$perm_id.' + } + ] +}'; + curl_setopt($user_ch, CURLOPT_POSTFIELDS,$user_body); + curl_setopt($user_ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($user_ch, CURLOPT_TIMEOUT, 30); + $user_json_return = curl_exec($user_ch); + $user_return = json_decode($user_json_return); + if($user_return->{'code'}=='500'||$user_return->{'code'}=='403'||$user_return->{'code'}=='404'){ + die($user_return->{'formatted_message'}); + } else { + $user_id = $user_return->{'id'}; + $params['model']->serviceProperties->save(['Permission ID' => $perm_id]); + $params['model']->serviceProperties->save(['AzuraCast ID' => $user_id]); + $params['model']->serviceProperties->save(['Username' => $sc_email]); + return 'success'; + } + } + } + + } catch (Exception $e) { + // Record the error in WHMCS's module log. + logModuleCall( + 'azuracast', + __FUNCTION__, + $params, + $e->getMessage(), + $e->getTraceAsString() + ); + + return $e->getMessage(); + } + + return 'success'; +} + +/** + * Suspend an instance of a product/service. + * + * Called when a suspension is requested. This is invoked automatically by WHMCS + * when a product becomes overdue on payment or can be called manually by admin + * user. + * + * @param array $params common module parameters + * + * @see https://developers.whmcs.com/provisioning-modules/module-parameters/ + * + * @return string "success" or an error message + */ +function azuracast_SuspendAccount(array $params) +{ + try { + // Call the service's suspend function, using the values provided by + // WHMCS in `$params`. + } catch (Exception $e) { + // Record the error in WHMCS's module log. + logModuleCall( + 'azuracast', + __FUNCTION__, + $params, + $e->getMessage(), + $e->getTraceAsString() + ); + + return $e->getMessage(); + } + + return 'success'; +} + +/** + * Un-suspend instance of a product/service. + * + * Called when an un-suspension is requested. This is invoked + * automatically upon payment of an overdue invoice for a product, or + * can be called manually by admin user. + * + * @param array $params common module parameters + * + * @see https://developers.whmcs.com/provisioning-modules/module-parameters/ + * + * @return string "success" or an error message + */ +function azuracast_UnsuspendAccount(array $params) +{ + try { + // Call the service's unsuspend function, using the values provided by + // WHMCS in `$params`. + } catch (Exception $e) { + // Record the error in WHMCS's module log. + logModuleCall( + 'azuracast', + __FUNCTION__, + $params, + $e->getMessage(), + $e->getTraceAsString() + ); + + return $e->getMessage(); + } + + return 'success'; +} + +/** + * Terminate instance of a product/service. + * + * Called when a termination is requested. This can be invoked automatically for + * overdue products if enabled, or requested manually by an admin user. + * + * @param array $params common module parameters + * + * @see https://developers.whmcs.com/provisioning-modules/module-parameters/ + * + * @return string "success" or an error message + */ +function azuracast_TerminateAccount(array $params) +{ + try { + // Call the service's terminate function, using the values provided by + // WHMCS in `$params`. + $station_id = $params['customfields']['Station ID']; + $azuracast_id = $params['customfields']['AzuraCast ID']; + $perm_id = $params['customfields']['Permission ID']; + $api_key = $params['serverpassword']; + if($params['serversecure']=='on'){ + $secure = 'https://'; + } else { + $secure = 'http://'; + } + $api_url = $secure.$params['serverhostname']; + $st_url = $api_url.'/api/admin/station/'.$station_id; + $st_ch = curl_init(); + $st_headers = array( + 'Accept: application/json', + 'Content-Type: application/json', + 'X-API-Key: '.$api_key, + ); + curl_setopt($st_ch, CURLOPT_URL, $st_url); + curl_setopt($st_ch, CURLOPT_HTTPHEADER, $st_headers); + curl_setopt($st_ch, CURLOPT_HEADER, 0); + $st_body = '{}'; + + curl_setopt($st_ch, CURLOPT_CUSTOMREQUEST, "DELETE"); + curl_setopt($st_ch, CURLOPT_POSTFIELDS,$st_body); + curl_setopt($st_ch, CURLOPT_RETURNTRANSFER, true); + + // Timeout in seconds + curl_setopt($st_ch, CURLOPT_TIMEOUT, 30); + + $st_json_return = curl_exec($st_ch); + $st_return = json_decode($st_json_return); + if($st_return->{'code'}=='500'||$st_return->{'code'}=='403'||$st_return->{'code'}=='404'){ + die($st_return->{'type'}); + } else { + $p_url = $api_url.'/api/admin/role/'.$perm_id; + $p_ch = curl_init(); + $p_headers = array( + 'Accept: application/json', + 'Content-Type: application/json', + 'X-API-Key: '.$api_key, + ); + curl_setopt($p_ch, CURLOPT_URL, $p_url); + curl_setopt($p_ch, CURLOPT_HTTPHEADER, $p_headers); + curl_setopt($p_ch, CURLOPT_HEADER, 0); + $p_body = '{}'; + + curl_setopt($p_ch, CURLOPT_CUSTOMREQUEST, "DELETE"); + curl_setopt($p_ch, CURLOPT_POSTFIELDS,$p_body); + curl_setopt($p_ch, CURLOPT_RETURNTRANSFER, true); + + // Timeout in seconds + curl_setopt($p_ch, CURLOPT_TIMEOUT, 30); + + $p_json_return = curl_exec($p_ch); + $p_return = json_decode($p_json_return); + if($p_return->{'code'}=='500'||$p_return->{'code'}=='403'||$p_return->{'code'}=='404'){ + die($p_return->{'type'}); + } else { + $u_url = $api_url.'/api/admin/user/'.$azuracast_id; + $u_ch = curl_init(); + $u_headers = array( + 'Accept: application/json', + 'Content-Type: application/json', + 'X-API-Key: '.$api_key, + ); + curl_setopt($u_ch, CURLOPT_URL, $u_url); + curl_setopt($u_ch, CURLOPT_HTTPHEADER, $u_headers); + curl_setopt($u_ch, CURLOPT_HEADER, 0); + $u_body = '{}'; + + curl_setopt($u_ch, CURLOPT_CUSTOMREQUEST, "DELETE"); + curl_setopt($u_ch, CURLOPT_POSTFIELDS,$u_body); + curl_setopt($u_ch, CURLOPT_RETURNTRANSFER, true); + + // Timeout in seconds + curl_setopt($u_ch, CURLOPT_TIMEOUT, 30); + + $u_json_return = curl_exec($u_ch); + $u_return = json_decode($u_json_return); + if($u_return->{'code'}=='500'||$u_return->{'code'}=='403'||$u_return->{'code'}=='404'){ + die($u_return->{'type'}); + } else { + return 'success'; + } + } + } + } catch (Exception $e) { + // Record the error in WHMCS's module log. + logModuleCall( + 'azuracast', + __FUNCTION__, + $params, + $e->getMessage(), + $e->getTraceAsString() + ); + + return $e->getMessage(); + } + + return 'success'; +} + +/** + * Change the password for an instance of a product/service. + * + * Called when a password change is requested. This can occur either due to a + * client requesting it via the client area or an admin requesting it from the + * admin side. + * + * This option is only available to client end users when the product is in an + * active status. + * + * @param array $params common module parameters + * + * @see https://developers.whmcs.com/provisioning-modules/module-parameters/ + * + * @return string "success" or an error message + */ +function azuracast_ChangePassword(array $params) +{ + try { + // Call the service's change password function, using the values + // provided by WHMCS in `$params`. + // + // A sample `$params` array may be defined as: + // + // ``` + // array( + // 'username' => 'The service username', + // 'password' => 'The new service password', + // ) + // ``` + } catch (Exception $e) { + // Record the error in WHMCS's module log. + logModuleCall( + 'azuracast', + __FUNCTION__, + $params, + $e->getMessage(), + $e->getTraceAsString() + ); + + return $e->getMessage(); + } + + return 'success'; +} + +/** + * Upgrade or downgrade an instance of a product/service. + * + * Called to apply any change in product assignment or parameters. It + * is called to provision upgrade or downgrade orders, as well as being + * able to be invoked manually by an admin user. + * + * This same function is called for upgrades and downgrades of both + * products and configurable options. + * + * @param array $params common module parameters + * + * @see https://developers.whmcs.com/provisioning-modules/module-parameters/ + * + * @return string "success" or an error message + */ +function azuracast_ChangePackage(array $params) +{ + try { + // Call the service's change password function, using the values + // provided by WHMCS in `$params`. + // + // A sample `$params` array may be defined as: + // + // ``` + // array( + // 'username' => 'The service username', + // 'configoption1' => 'The new service disk space', + // 'configoption3' => 'Whether or not to enable FTP', + // ) + // ``` + } catch (Exception $e) { + // Record the error in WHMCS's module log. + logModuleCall( + 'azuracast', + __FUNCTION__, + $params, + $e->getMessage(), + $e->getTraceAsString() + ); + + return $e->getMessage(); + } + + return 'success'; +} + +/** + * Renew an instance of a product/service. + * + * Attempt to renew an existing instance of a given product/service. This is + * called any time a product/service invoice has been paid. + * + * @param array $params common module parameters + * + * @see https://developers.whmcs.com/provisioning-modules/module-parameters/ + * + * @return string "success" or an error message + */ +function azuracast_Renew(array $params) +{ + try { + // Call the service's provisioning function, using the values provided + // by WHMCS in `$params`. + // + // A sample `$params` array may be defined as: + // + // ``` + // array( + // 'domain' => 'The domain of the service to provision', + // 'username' => 'The username to access the new service', + // 'password' => 'The password to access the new service', + // 'configoption1' => 'The amount of disk space to provision', + // 'configoption2' => 'The new services secret key', + // 'configoption3' => 'Whether or not to enable FTP', + // ... + // ) + // ``` + } catch (Exception $e) { + // Record the error in WHMCS's module log. + logModuleCall( + 'azuracast', + __FUNCTION__, + $params, + $e->getMessage(), + $e->getTraceAsString() + ); + + return $e->getMessage(); + } + + return 'success'; +} + +/** + * Test connection with the given server parameters. + * + * Allows an admin user to verify that an API connection can be + * successfully made with the given configuration parameters for a + * server. + * + * When defined in a module, a Test Connection button will appear + * alongside the Server Type dropdown when adding or editing an + * existing server. + * + * @param array $params common module parameters + * + * @see https://developers.whmcs.com/provisioning-modules/module-parameters/ + * + * @return array + */ +function azuracast_TestConnection(array $params) +{ + try { + // Call the service's connection test function. + + $success = true; + $errorMsg = ''; + } catch (Exception $e) { + // Record the error in WHMCS's module log. + logModuleCall( + 'azuracast', + __FUNCTION__, + $params, + $e->getMessage(), + $e->getTraceAsString() + ); + + $success = false; + $errorMsg = $e->getMessage(); + } + + return array( + 'success' => $success, + 'error' => $errorMsg, + ); +} + +/** + * Additional actions an admin user can invoke. + * + * Define additional actions that an admin user can perform for an + * instance of a product/service. + * + * @see azuracast_buttonOneFunction() + * + * @return array + */ +function azuracast_AdminCustomButtonArray() +{ + return array( + + ); +} + +/** + * Additional actions a client user can invoke. + * + * Define additional actions a client user can perform for an instance of a + * product/service. + * + * Any actions you define here will be automatically displayed in the available + * list of actions within the client area. + * + * @return array + */ +function azuracast_ClientAreaCustomButtonArray() +{ + return array( + + ); +} + +/** + * Custom function for performing an additional action. + * + * You can define an unlimited number of custom functions in this way. + * + * Similar to all other module call functions, they should either return + * 'success' or an error message to be displayed. + * + * @param array $params common module parameters + * + * @see https://developers.whmcs.com/provisioning-modules/module-parameters/ + * @see azuracast_AdminCustomButtonArray() + * + * @return string "success" or an error message + */ +function azuracast_buttonOneFunction(array $params) +{ + try { + // Call the service's function, using the values provided by WHMCS in + // `$params`. + } catch (Exception $e) { + // Record the error in WHMCS's module log. + logModuleCall( + 'azuracast', + __FUNCTION__, + $params, + $e->getMessage(), + $e->getTraceAsString() + ); + + return $e->getMessage(); + } + + return 'success'; +} + +/** + * Custom function for performing an additional action. + * + * You can define an unlimited number of custom functions in this way. + * + * Similar to all other module call functions, they should either return + * 'success' or an error message to be displayed. + * + * @param array $params common module parameters + * + * @see https://developers.whmcs.com/provisioning-modules/module-parameters/ + * @see azuracast_ClientAreaCustomButtonArray() + * + * @return string "success" or an error message + */ +function azuracast_actionOneFunction(array $params) +{ + try { + // Call the service's function, using the values provided by WHMCS in + // `$params`. + } catch (Exception $e) { + // Record the error in WHMCS's module log. + logModuleCall( + 'azuracast', + __FUNCTION__, + $params, + $e->getMessage(), + $e->getTraceAsString() + ); + + return $e->getMessage(); + } + + return 'success'; +} + +/** + * Admin services tab additional fields. + * + * Define additional rows and fields to be displayed in the admin area service + * information and management page within the clients profile. + * + * Supports an unlimited number of additional field labels and content of any + * type to output. + * + * @param array $params common module parameters + * + * @see https://developers.whmcs.com/provisioning-modules/module-parameters/ + * @see azuracast_AdminServicesTabFieldsSave() + * + * @return array + */ +function azuracast_AdminServicesTabFields(array $params) +{ + try { + // Call the service's function, using the values provided by WHMCS in + // `$params`. + $response = array(); + + // Return an array based on the function's response. + return array( + + ); + } catch (Exception $e) { + // Record the error in WHMCS's module log. + logModuleCall( + 'azuracast', + __FUNCTION__, + $params, + $e->getMessage(), + $e->getTraceAsString() + ); + + // In an error condition, simply return no additional fields to display. + } + + return array(); +} + +/** + * Execute actions upon save of an instance of a product/service. + * + * Use to perform any required actions upon the submission of the admin area + * product management form. + * + * It can also be used in conjunction with the AdminServicesTabFields function + * to handle values submitted in any custom fields which is demonstrated here. + * + * @param array $params common module parameters + * + * @see https://developers.whmcs.com/provisioning-modules/module-parameters/ + * @see azuracast_AdminServicesTabFields() + */ +function azuracast_AdminServicesTabFieldsSave(array $params) +{ + // Fetch form submission variables. + $originalFieldValue = isset($_REQUEST['azuracast_original_uniquefieldname']) + ? $_REQUEST['azuracast_original_uniquefieldname'] + : ''; + + $newFieldValue = isset($_REQUEST['azuracast_uniquefieldname']) + ? $_REQUEST['azuracast_uniquefieldname'] + : ''; + + // Look for a change in value to avoid making unnecessary service calls. + if ($originalFieldValue != $newFieldValue) { + try { + // Call the service's function, using the values provided by WHMCS + // in `$params`. + } catch (Exception $e) { + // Record the error in WHMCS's module log. + logModuleCall( + 'azuracast', + __FUNCTION__, + $params, + $e->getMessage(), + $e->getTraceAsString() + ); + + // Otherwise, error conditions are not supported in this operation. + } + } +} + +/** + * Perform single sign-on for a given instance of a product/service. + * + * Called when single sign-on is requested for an instance of a product/service. + * + * When successful, returns a URL to which the user should be redirected. + * + * @param array $params common module parameters + * + * @see https://developers.whmcs.com/provisioning-modules/module-parameters/ + * + * @return array + */ +function azuracast_ServiceSingleSignOn(array $params) +{ + try { + // Call the service's single sign-on token retrieval function, using the + // values provided by WHMCS in `$params`. + $response = array(); + + return array( + 'success' => true, + 'redirectTo' => 'http://'.$params['serverhostname'], + ); + } catch (Exception $e) { + // Record the error in WHMCS's module log. + logModuleCall( + 'azuracast', + __FUNCTION__, + $params, + $e->getMessage(), + $e->getTraceAsString() + ); + + return array( + 'success' => false, + 'errorMsg' => $e->getMessage(), + ); + } +} + +/** + * Perform single sign-on for a server. + * + * Called when single sign-on is requested for a server assigned to the module. + * + * This differs from ServiceSingleSignOn in that it relates to a server + * instance within the admin area, as opposed to a single client instance of a + * product/service. + * + * When successful, returns a URL to which the user should be redirected to. + * + * @param array $params common module parameters + * + * @see https://developers.whmcs.com/provisioning-modules/module-parameters/ + * + * @return array + */ +function azuracast_AdminSingleSignOn(array $params) +{ + try { + // Call the service's single sign-on admin token retrieval function, + // using the values provided by WHMCS in `$params`. + $response = array(); + + return array( + 'success' => true, + 'redirectTo' => 'http://'.$params['serverhostname'], + ); + } catch (Exception $e) { + // Record the error in WHMCS's module log. + logModuleCall( + 'azuracast', + __FUNCTION__, + $params, + $e->getMessage(), + $e->getTraceAsString() + ); + + return array( + 'success' => false, + 'errorMsg' => $e->getMessage(), + ); + } +} + +/** + * Client area output logic handling. + * + * This function is used to define module specific client area output. It should + * return an array consisting of a template file and optional additional + * template variables to make available to that template. + * + * The template file you return can be one of two types: + * + * * tabOverviewModuleOutputTemplate - The output of the template provided here + * will be displayed as part of the default product/service client area + * product overview page. + * + * * tabOverviewReplacementTemplate - Alternatively using this option allows you + * to entirely take control of the product/service overview page within the + * client area. + * + * Whichever option you choose, extra template variables are defined in the same + * way. This demonstrates the use of the full replacement. + * + * Please Note: Using tabOverviewReplacementTemplate means you should display + * the standard information such as pricing and billing details in your custom + * template or they will not be visible to the end user. + * + * @param array $params common module parameters + * + * @see https://developers.whmcs.com/provisioning-modules/module-parameters/ + * + * @return array + */ +function azuracast_ClientArea(array $params) +{ + // Determine the requested action and set service call parameters based on + // the action. + $requestedAction = isset($_REQUEST['customAction']) ? $_REQUEST['customAction'] : ''; + + if ($requestedAction == 'manage') { + $serviceAction = 'get_usage'; + $templateFile = 'templates/manage.tpl'; + } else { + $serviceAction = 'get_stats'; + $templateFile = 'templates/overview.tpl'; + } + + try { + // Call the service's function based on the request action, using the + // values provided by WHMCS in `$params`. + $response = array(); + + $extraVariable1 = 'abc'; + $extraVariable2 = '123'; + + return array( + 'tabOverviewReplacementTemplate' => $templateFile, + 'templateVariables' => array( + 'extraVariable1' => $extraVariable1, + 'extraVariable2' => $extraVariable2, + ), + ); + } catch (Exception $e) { + // Record the error in WHMCS's module log. + logModuleCall( + 'azuracast', + __FUNCTION__, + $params, + $e->getMessage(), + $e->getTraceAsString() + ); + + // In an error condition, display an error page. + return array( + 'tabOverviewReplacementTemplate' => 'error.tpl', + 'templateVariables' => array( + 'usefulErrorHelper' => $e->getMessage(), + ), + ); + } +} diff --git a/azuracast/hooks.php b/azuracast/hooks.php new file mode 100644 index 0000000..0ed7067 --- /dev/null +++ b/azuracast/hooks.php @@ -0,0 +1,110 @@ +getChild('My Services Actions'))) { + + // define new sidebar panel + $customPanel = $secondarySidebar->addChild('AzuraCast Panel'); + + // set panel attributes + $customPanel->moveToFront() + ->setIcon('fa-user') + ->setBodyHtml( + 'Your HTML output goes here...' + ) + ->setFooterHtml( + 'Footer HTML can go here...' + ); + + // define link + $customPanel->addChild( + 'Sample Link Menu Item', + array( + 'uri' => 'clientarea.php?action=services&module=azuracast', + 'icon' => 'fa-list-alt', + 'order' => 2, + ) + ); + + } +}); diff --git a/azuracast/lib/README.md b/azuracast/lib/README.md new file mode 100644 index 0000000..7e59801 --- /dev/null +++ b/azuracast/lib/README.md @@ -0,0 +1 @@ +Include libraries and third party modules here. diff --git a/azuracast/logo.png b/azuracast/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..314fffcd5dc64ce8d40f2eadc8c70b711f2ccd77 GIT binary patch literal 12464 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 Something went wrong. + +
+

Extra template variables work here too: {$usefulErrorHelper}

+
+ +

Please go back and try again.

+ +

If the problem persists, please contact support.

diff --git a/azuracast/templates/manage.tpl b/azuracast/templates/manage.tpl new file mode 100644 index 0000000..c84b8c4 --- /dev/null +++ b/azuracast/templates/manage.tpl @@ -0,0 +1,48 @@ +

Custom Client Area Page

+ +

This is an example of an additional custom page within a module's client area product management pages.

+ +

Everything that is available in the overview is also available in this template file along with any custom defined template variables.

+ +
+ +
+
+ {$LANG.orderproduct} +
+
+ {$groupname} - {$product} +
+
+ +
+
+ Extra Variable 1 +
+
+ {$extraVariable1} +
+
+ +
+
+ Extra Variable 2 +
+
+ {$extraVariable2} +
+
+ +
+ +
+
+
+ + +
+
+
diff --git a/azuracast/templates/overview.tpl b/azuracast/templates/overview.tpl new file mode 100644 index 0000000..d4f6324 --- /dev/null +++ b/azuracast/templates/overview.tpl @@ -0,0 +1,288 @@ +

Overview

+ +

Overview output goes here...

+ +

Please Remember: When overriding the default product overview output, it is important to provide the product details and information that are normally displayed on this page. These are provided below.

+ +
+ Any variables you define inside the ClientArea module function can also be accessed and used here, for example: {$extraVariable1} & {$extraVariable2} +
+ +

{$LANG.clientareaproductdetails}

+ +
+ +
+
+ {$LANG.clientareahostingregdate} +
+
+ {$regdate} +
+
+ +
+
+ {$LANG.orderproduct} +
+
+ {$groupname} - {$product} +
+
+ +{if $type eq "server"} + {if $domain} +
+
+ {$LANG.serverhostname} +
+
+ {$domain} +
+
+ {/if} + {if $dedicatedip} +
+
+ {$LANG.primaryIP} +
+
+ {$dedicatedip} +
+
+ {/if} + {if $assignedips} +
+
+ {$LANG.assignedIPs} +
+
+ {$assignedips|nl2br} +
+
+ {/if} + {if $ns1 || $ns2} +
+
+ {$LANG.domainnameservers} +
+
+ {$ns1}
{$ns2} +
+
+ {/if} +{else} + {if $domain} +
+
+ {$LANG.orderdomain} +
+
+ {$domain} + {$LANG.visitwebsite} +
+
+ {/if} + {if $username} +
+
+ {$LANG.serverusername} +
+
+ {$username} +
+
+ {/if} + {if $password} +
+
+ {$LANG.serverpassword} +
+
+ {$password} +
+
+ {/if} + {if $serverdata} +
+
+ {$LANG.servername} +
+
+ {$serverdata.hostname} +
+
+
+
+ {$LANG.domainregisternsip} +
+
+ {$serverdata.ipaddress} +
+
+ {if $serverdata.nameserver1 || $serverdata.nameserver2 || $serverdata.nameserver3 || $serverdata.nameserver4 || $serverdata.nameserver5} +
+
+ {$LANG.domainnameservers} +
+
+ {if $serverdata.nameserver1}{$serverdata.nameserver1} ({$serverdata.nameserver1ip})
{/if} + {if $serverdata.nameserver2}{$serverdata.nameserver2} ({$serverdata.nameserver2ip})
{/if} + {if $serverdata.nameserver3}{$serverdata.nameserver3} ({$serverdata.nameserver3ip})
{/if} + {if $serverdata.nameserver4}{$serverdata.nameserver4} ({$serverdata.nameserver4ip})
{/if} + {if $serverdata.nameserver5}{$serverdata.nameserver5} ({$serverdata.nameserver5ip})
{/if} +
+
+ {/if} + {/if} +{/if} + +{if $dedicatedip} +
+
+ {$LANG.domainregisternsip} +
+
+ {$dedicatedip} +
+
+{/if} + +{foreach from=$configurableoptions item=configoption} +
+
+ {$configoption.optionname} +
+
+ {if $configoption.optiontype eq 3} + {if $configoption.selectedqty} + {$LANG.yes} + {else} + {$LANG.no} + {/if} + {elseif $configoption.optiontype eq 4} + {$configoption.selectedqty} x {$configoption.selectedoption} + {else} + {$configoption.selectedoption} + {/if} +
+
+{/foreach} + +{foreach from=$productcustomfields item=customfield} +
+
+ {$customfield.name} +
+
+ {$customfield.value} +
+
+{/foreach} + +{if $lastupdate} +
+
+ {$LANG.clientareadiskusage} +
+
+ {$diskusage}MB / {$disklimit}MB ({$diskpercent}) +
+
+
+
+ {$LANG.clientareabwusage} +
+
+ {$bwusage}MB / {$bwlimit}MB ({$bwpercent}) +
+
+{/if} + +
+
+ {$LANG.orderpaymentmethod} +
+
+ {$paymentmethod} +
+
+ +
+
+ {$LANG.firstpaymentamount} +
+
+ {$firstpaymentamount} +
+
+ +
+
+ {$LANG.recurringamount} +
+
+ {$recurringamount} +
+
+ +
+
+ {$LANG.clientareahostingnextduedate} +
+
+ {$nextduedate} +
+
+ +
+
+ {$LANG.orderbillingcycle} +
+
+ {$billingcycle} +
+
+ +
+
+ {$LANG.clientareastatus} +
+
+ {$status} +
+
+ +{if $suspendreason} +
+
+ {$LANG.suspendreason} +
+
+ {$suspendreason} +
+
+{/if} + +
+ +