WHMCS 开发简介

开发官网:https://developers.whmcs.com/

快速开始

你想做什么?

  1. 自定义WHMCS客户端主题。
    https://developers.whmcs.com/themes/getting-started

2.创建供应模块
https://developers.whmcs.com/provisioning-modules
供应模块可以在WHMCS中为服务供应和提供管理。他们有时也指的是产品或者服务模块。

3.创建插件模块
https://developers.whmcs.com/addon-modules
插件模块允许你穿件管理页面和通过钩子函数去扩展WHMCS。

4.创建域名注册模块
https://developers.whmcs.com/domain-registrars
WHMCS Registrar模块允许注册和管理域名。Registrar也指的是域名模块。

5.创建支付方式模块
https://developers.whmcs.com/payment-gateways

6.使用API让WHMCS与第三方系统进行交互
https://developers.whmcs.com/api

7.浏览API
https://developers.whmcs.com/api-reference
WHMCS API允许你执行操作与第三方系统进行交互。

8.浏览钩子参考
https://developers.whmcs.com/hooks-reference
一系列完整的钩子列表在WHMCS中是可用的。

9.从WHMCS中与数据库进行交互
https://developers.whmcs.com/advanced/db-interaction

10.创建一种新的语言。
https://developers.whmcs.com/languages/adding-a-language


11.新建一个sidebar:
whmcs账号密码: liaodalin19903@126.com / liaodalin19903
https://www.whmcs.com/members/viewticket.php?tid=PCT-982190&c=9a4JdGbt

12.要创建额外的变量,在hooks中创建:
https://stackoverflow.com/questions/46897241/how-to-include-external-php-variable-outside-of-whmcs-into-whmcs

13.smarty中字符串拼接:
https://www.jb51.net/article/46790.htm

14.{$smarty.server.DOCUMENT_ROOT}
https://stackoverflow.com/questions/51260438/how-can-i-use-the-serverdocument-root-in-smarty-template

15.从hooks添加自定义变量到whmcs
比如我有一个test.hooks

<?php

add_hook("ClientAreaPageProductsServices", 1, function($vars){

    // 添加扩展变量
    $extraTemplateVariables = array();

    $extraTemplateVariables['test_list'] = ['a', 'b', 'c', 'd'];
    $extraTemplateVariables['selected_product'] = ''; // 选择中的产品

    return $extraTemplateVariables;
});

我们在hooks/example.php中引入:

<?php

include($_SERVER['DOCUMENT_ROOT'] . '/templates/NeWorld/qicloud_ext/qicloud_products/clientareaproducts_ext/hooks/clientareaproducts.php');

使用:

<h1>{$test_list[2]}</h1>
  1. whmcs的 OAuth可以允许三方应用访问whmcs:
    https://developers.whmcs.com/oauth/

主题开发

17.创建页面:
https://developers.whmcs.com/advanced/creating-pages/

18.设置menu item文字的两种方式:
https://developers.whmcs.com/themes/navigation/

Notice how in the above we first retrieve the My Account menu item, followed by the Billing Information menu item which is a child within that.The same logic should be applied to all dropdown menu items

<?php

use WHMCS\View\Menu\Item as MenuItem;

add_hook('ClientAreaPrimarySidebar', 1, function(MenuItem $primarySidebar)
{
    $primarySidebar->getChild("My Account")
        ->getChild("Billing Information")
        ->setLabel("Custom Text Here");
});

sidebar和其余所有的下拉的取法是相同的逻辑。

20.改变路径导航路径:

<?php

use WHMCS\View\Menu\Item as MenuItem;

add_hook('ClientAreaPrimaryNavbar', 1, function (MenuItem $primaryNavbar)
{
    $navItem = $primaryNavbar->getChild('Support');
    if (is_null($navItem)) {
        return;
    }

    $navItem = $navItem->getChild('Announcements');
    if (is_null($navItem)) {
        return;
    }

    $navItem->setUri('https://www.example.com/3rdpartyblogsystem');  // 设置为第三方的博客系统

});

21.php代码中,需要翻译是这样做 Lang::trans :

<?php

use WHMCS\View\Menu\Item as MenuItem;

add_hook('ClientAreaPrimaryNavbar', 1, function (MenuItem $primaryNavbar)
{
    if (!is_null($primaryNavbar->getChild('Support'))) {
        $primaryNavbar->getChild('Support')
            ->addChild('Emergency Contacts', array(
                'label' => Lang::trans('emergencyContacts'),
                'uri' => 'emergency.php',
                'order' => '100',
            ));
    }
});

22.PHP逻辑
官方推荐所有的PHP逻辑都通过hooks去做。
Hook是在页面呈现时执行自己的PHP逻辑的唯一面向未来的方法。

在以前,Smarty允许您直接在模板文件中定义自定义PHP逻辑。 用户和第三方开发人员经常使用它作为执行附加逻辑和定义其他模板输出的快捷方式。

但是,在Smarty3之后,{php}标签已经被移除了,我们只提供遗留支持,以便为使用我们平台并依赖此功能的开发人员和用户轻松过渡。

案例:
https://developers.whmcs.com/themes/php/

23.测试

WHMCS允许你预览template,在你发布之前。
可以通过提那家?systpl=xxxxurl 参数来实现。

比如:你的新主题被命名为mytemplate,并且你的WHMCS客户区是落在:

http://www.yourdomain.com/whmcs/

那么你可以通过下面的方式导航过去:

http://www.yourdomain.com/whmcs/?systpl=mytemplate

模板将在您的浏览器会话期间存储,允许您使用新theme测试客户区的所有区域。

发布你的模板

按照下面步骤发布:
1.登录管理员区
2.设置->常规设置
3.在“常规”选项卡上的“模板”设置下,选择上面创建的模板的名称
4.点击保存更改,您网站的访问者将立即开始看到你的新模板。

24.调试

语法错误可以导致一个页面不能完全被渲染。
其他的经常引起错误的原因如下:
1)使用已经被移除的Smarty包的方法。
2)自己写的或者三方的模块不稳定。
3)你使用了{php }标签,但是你没有在系统中设置『允许PHP tags』(设置->常规设置->安全)中去打开。

排错

如果在更改模板文件后看到空白页,请检查“实用程序”>“日志”中的“活动日志”以查找任何已记录的错误消息。(现在估计在其他选项->日志记录中)

提示:
如果你没有发现任何有用日志,那么转换到一个不同的模板中去决定是否这个问题也出现在其他的模板中。

25.Smarty,WHMCS是使用Smarty模板引擎。
Smarty是一个快速而强大的模板系统,具有大量功能,可以轻松灵活地使用WHMCS模板。

Smarty手册:
https://www.smarty.net/docs/en/

26.GitHub

下面的模板可以从GitHub获取:
1)Six 客户区模板
https://github.com/WHMCS/templates-six
2)标准卡订单表单模板
WHMCS默认的购物车模板。
https://github.com/WHMCS/orderforms-standard_cart


语言

27.lang介绍
WHMCS是多语言,支持25种语言。
语言文件在lang文件夹下,客户端和管理员端都有。
如果你想自定义任何语言字符串,我们建议使用重写。

https://developers.whmcs.com/languages/overrides/

详情查看:https://developers.whmcs.com/languages/

模块

28.模块介绍

模块是一组函数,为WHMCS平台提供附加功能,最常用于与第三方服务和API集成。

有下面几种模块类型(重要):
1)供应模块
通过API实现的供应和管理产品&服务。
2)插件模块
在WHMCS中提供额外的功能的模块。
3)域名注册模块
联系到域名注册去允许可用性检测,域名注册和管理。
4)支付方式模块
与支付网关提供者交互去收集和处理付款。
5)通知提供者
增加额外的与通知系统相关的通知服务。

29.模块开发入门
首先,在你开发模块之前,选择开发哪种模块。

1)供应模块
供应模块,也指的是产品或者服务模块,允许你创建模块去提供和管理产品&服务。
https://developers.whmcs.com/provisioning-modules/

2)插件模块
Addon Modules允许您创建提供客户端和/或管理区域输出的模块和扩展,这些模块和扩展不直接链接到单个产品/服务。
https://developers.whmcs.com/addon-modules/

3)支付网关模块
网关模块允许您将WHMCS与其他支付和信用卡处理器连接,以便处理和获取付款。 支付网关模块包括:

第三方网关 – 客户离开网站付款并在付款流程完成时返回。
商家网关 – 客户在不离开WHMCS的情况下输入信用卡详细信息并通过API处理付款。
标记化网关 – 在WHMCS内部或外部输入信用卡详细信息,并生成并存储令牌以满足将来的计费需求。

4)注册器模块
注册器模块(也称为域模块)允许您创建模块,以允许在WHMCS中注册和管理域。

我们可以在WHMCS Github page查看相关的代码实例demo。

相关阅读

1)Code Samples
代码示例,在GitHub上面我们做了四种模块的相关代码。

2)Style Guide
推荐的编程风格和使用WHMCS进行开发的最佳实践。

3)Hooks Guide
钩子允许你在WHMCS内发生事件时执行自己的代码。

4)API Guide
API允许您在WHMCS中执行操作和操作。

30.代码示例
我们在Github上写了一系列代码示例。

Gateway Module:
https://github.com/WHMCS/sample-gateway-module
Merchant Gateway:
https://github.com/WHMCS/sample-merchant-gateway
Provisioning Module:
https://github.com/WHMCS/sample-provisioning-module
Domain Registrar Module:
https://github.com/WHMCS/sample-registrar-module
Addon Module:
https://github.com/WHMCS/sample-addon-module

31.样式指南
以下介绍了使用WHMCS进行开发时的推荐编程风格和最佳实践。

PHP 代码标签

总是使用<?php?>来分隔PHP代码,而不是简写,<??>。 这是最便携的格式,可确保不同操作系统和设置的兼容性。

如果文件是纯PHP代码,则最好省略文件末尾的PHP结束标记。 这可以防止在PHP结束标记之后添加意外的空格或新行,这可能会导致不必要的副作用,包括“已发送标头”错误,XHTML / XML验证问题以及其他问题。

缩进和空格

使用4个空格的缩进,没有制表符。

行末尾应该没有尾随空格。

文件格式应使用\ n作为行结尾(Unix行结尾),而不是\ r \ n(Windows行结尾)。

所有文件应以单个换行符结尾(\ n)。 这样可以避免冗长的“\文件末尾没有新行”警告,并且当行添加到文件末尾时更清楚地显示更改内容。

PSR代码标准

PHP标准建议书(PSR)是由PHP Framework Interop Group发布的PHP规范。 它包含了应该被认为是确保共享PHP代码之间高水平技术互操作性所需的标准编码元素。

在WHMCS,我们遵循我们创建的所有代码的PSR-1和PSR-2标准,我们强烈建议您这样做:

字符编码

所有PHP文件都应该使用没有BOM的UTF-8进行编码(没有字节顺序标记)。

32.WHMCS市场

WHMCS Marketplace允许WHMCS用户连接,查找和发现WHMCS平台的附加组件和扩展。
对于开发人员而言,它为您提供了一个很好的机会,让您可以获得您的创作曝光和潜在用户和客户的可见性。
提交是免费的,我们强烈建议您提交您的作品。

OAuth

钩子

33.介绍
钩子允许您在WHMCS内发生事件时执行自己的代码。

34.入门
以下步骤演示了如何在WHMCS中创建钩子函数。

创建你的钩子文件

挂钩位于/includes/hooks/目录中的文件内(或作为模块的一部分 – 请参阅模块挂钩)。

创建helloworld.php文件:

touch ~/includes/hooks/helloworld.php

添加钩子函数

钩子函数可以被称为命名函数或者闭包。
下面是一个示例钩子,它将在ClientAdd事件发生时执行:

<?php
/**
 * Register hook function call.
 *
 * @param string $hookPoint The hook point to call
 * @param integer $priority The priority for the given hook function
 * @param string|function Function name to call or anonymous function.
 *
 * @return Depends on hook function point.
 */
add_hook('ClientAdd', 1, function ($vars)
{
    $userid = $vars['userid'];
    $firstname = $vars['firstname'];
    $lastname = $vars['lastname'];
    $email = $vars['email'];
    $password = $vars['password'];

    // Run code to create remote forum account here...
});

选择的变量将传递到您的挂钩点。 您收到的变量取决于被调用的操作以及可用的数据。

注意:这个$vars中有userid, firstname, password 等,为什么这里可以知道,请参考:Hook Indexes中去找。

某些挂钩点还允许您返回值,在某些情况下,您提供的响应可以更改程序流以允许您覆盖默认行为。

提示:使用命名函数时,我们建议您在函数名前加上您和您的代码所特有的内容,以防止与未来代码发生潜在的命名冲突。

35.定义优先级

每一个钩子函数必须要注册优先级。
优先级定义了在为同一个挂钩点注册多个挂钩时钩子应该运行的顺序。
是一个整数值。

36.模块钩子

模块挂钩遵循与常规挂钩相同的原则。

在模块中定义挂钩

要将钩子作为模块的一部分提供,请在模块目录的根目录中创建名为hooks.php的文件。

WHMCS将在每次页面加载时检测并加载此挂钩文件。

仅在激活和配置模块时检测到挂钩文件。 如果在模块激活后添加挂钩文件,则可能需要取消激活并重新激活模块,以便WHMCS识别它。

37.钩子案例

比如:
/includes/hooks/samplehook.php

<?php
/**
 * Register hook function call.
 *
 * @param string $hookPoint The hook point to call
 * @param integer $priority The priority for the given hook function
 * @param string|function Function name to call or anonymous function.
 *
 * @return Depends on hook function point.
 */
add_hook('ClientAdd', 1, function ($vars)
{
    $userid = $vars['userid'];
    $firstname = $vars['firstname'];
    $lastname = $vars['lastname'];
    $email = $vars['email'];
    $password = $vars['password'];

    // Run code to create remote forum account here...
});

38.钩子索引,查看:
https://developers.whmcs.com/hooks/hook-index/

API

39.介绍API

WHMCS API允许你从三方和自定义的代码执行与WHMCS进行操作。

40.入门
两种方式去调用API。
1)外部的API
当从WHMCS安装远程托管进行呼叫的系统时,应使用外部API。

此API接受位于以下位置的API端点的POST请求:

https://www.yourdomain.com/path/to/whmcs/includes/api.php

2)内部API
在WHMCS系统内进行API调用时,应使用内部API。
例如,来自WHMCS安装本地的模块,挂钩或其他自定义代码。

41.认证
使用API需要API身份验证凭据。
同样,关联的管理员用户必须具有授予其管理角色组的API访问权限。

可以为管理区域内的管理员用户生成API身份验证凭据,如WHMCS文档中所述

每个API请求都需要进行身份验证。

使用API的凭证进行认证

在WHMCS管理区域内创建管理API身份验证凭据时,将根据请求参数identifier和secret对API请求进行身份验证。可以通过http://docs.whmcs.com/API_Authentication_Credentials#Creating_Admin_API_Authentication_Credentials 去获得identifier和secret。

$api_identifier = 'D4j1dKYE3g40VROOPCGyJ9zRwP0ADJIv';
$api_secret = 'F1CKGXRIpylMfsrig3mwwdSdYUdLiFlo';

$postfields = array(
    'identifier' => $api_identifier,
    'secret' => $api_secret,
    'action' => $api_call,
    'responsetype' => $response_type,
);

为了与现有集成的向前兼容性,identifier和secret也可以分别在username和password字段中传递。 以这种方式传递的有效标识符和秘密组合也将导致成功的身份验证。

登录认证

在WHMCS verison 7.2之前,基于管理员登录凭据验证身份验证,而不是API身份验证凭据。 这种身份验证方法仍然支持向后兼容性,但在WHMCS的未来版本中可能不推荐使用。

要使用管理员登录凭据进行身份验证,请传递管理员用户名和相应管理员密码的MD5哈希值。

$username = "your_admin_login_username";
$password = "your_admin_login_password";

$postfields = array(
    'username' => $username,
    'password' => md5($password),
    'action' => $api_call,
    'responsetype' => $response_type,
);

42.内部API

在WHMCS系统内进行API调用时,应使用内部API。
此常见用途包括模块,挂钩或WHMCS安装本地的其他自定义代码。

使用案例:

<?php
/**
 * WHMCS Sample Local API Call
 *
 * @package    WHMCS
 * @author     WHMCS Limited <development@whmcs.com>
 * @copyright  Copyright (c) WHMCS Limited 2005-2016
 * @license    http://www.whmcs.com/license/ WHMCS Eula
 * @version    $Id$
 * @link       http://www.whmcs.com/
 */

// Define parameters
$command = 'SendEmail';
$values = array(
    'messagename' => 'Test Template',
    'id' => '1',
);
$adminuser = 'AdminUsername';

// Call the localAPI function
$results = localAPI($command, $values, $adminuser);
if ($results['result'] == 'success') {
    echo 'Message sent successfully!';
} else {
    echo "An Error Occurred: " . $results['result'];
}

43.API索引:https://developers.whmcs.com/api/api-index/

开发进阶

44.创建页面

创建自己的客户区页面应该通过创建带有客户区输出的Addon模块来完成。
但是,如果您愿意,可以使用以下模板创建独立页面。

<?php

use WHMCS\ClientArea;
use WHMCS\Database\Capsule;

define('CLIENTAREA', true);

require __DIR__ . '/init.php';

$ca = new ClientArea();

$ca->setPageTitle('Your Page Title Goes Here');

$ca->addToBreadCrumb('index.php', Lang::trans('globalsystemname'));
$ca->addToBreadCrumb('mypage.php', 'Your Custom Page Name');

$ca->initPage();

//$ca->requireLogin(); // Uncomment this line to require a login to access this page

// To assign variables to the template system use the following syntax.
// These can then be referenced using {$variablename} in the template.

//$ca->assign('variablename', $value);

// Check login status
if ($ca->isLoggedIn()) {

    /**
     * User is logged in - put any code you like here
     *
     * Here's an example to get the currently logged in clients first name
     */

    $clientName = Capsule::table('tblclients')
        ->where('id', '=', $ca->getUserID())->pluck('firstname');
        // 'pluck' was renamed within WHMCS 7.0.  Replace it with 'value' instead.
        // ->where('id', '=', $ca->getUserID())->value('firstname');
    $ca->assign('clientname', $clientName);

} else {

    // User is not logged in
    $ca->assign('clientname', 'Random User');

}

/**
 * Set a context for sidebars
 *
 * @link http://docs.whmcs.com/Editing_Client_Area_Menus#Context
 */
Menu::addContext();

/**
 * Setup the primary and secondary sidebars
 *
 * @link http://docs.whmcs.com/Editing_Client_Area_Menus#Context
 */
Menu::primarySidebar('announcementList');
Menu::secondarySidebar('announcementList');

# Define the template filename to be used without the .tpl extension

$ca->setTemplate('mypage');

$ca->output();

该示例演示了页面的属性:

  • 怎么初始化页面
  • 如何引用语言文件变量(Lang::trans)
  • 如何判断一个用户是否已经登录($ca->isLoggedIn())
  • 怎么定义模板变量($ca->assign)
  • 如何设置要使用的模板然后输出它

模板文件应该是活动WHMCS系统模板文件夹中的文件名。 因此,对于上面的示例,路径将是/templates/default/mypage.tpl

现在准备测试时,将PHP文件上传到根WHMCS目录,将模板文件上传到活动模板目录。 然后访问浏览器中的PHP文件进行尝试。

提示:
以这种方式创建的自定义页面应始终位于根WHMCS目录中。 不支持尝试在根目录之外使用此代码。

45.与数据库交互

WHMCS 6.0及更高版本利用数据库连接库来确保与现代PHP环境和最佳实践的兼容性。 它基于Laravel框架的数据库组件。 该库包括称为“Capsule”的数据库抽象层(DBAL)和称为“Eloquent”的对象关系映射(ORM)库。

Capsule DBAL组件向WHMCS引入了两个库,一个用于运行数据库查询的查询管理器和一个用于表管理的抽象API的模式管理器。 Capsule的基础PDO连接也可用于高级数据库使用。 Capsule有三种静态方法可以访问这些组件:

Capsule::table(string $tableName): 访问给定表的查询管理器。
Capsule::schema(): 访问WHMCS数据库的架构管理器.
Capsule::connection():访问连接管理器以与底层数据库连接进行交互。

弃用的方法

以前使用的SQL Helper函数仍然存在于WHMCS中,但现在已弃用,可能会在产品的更高版本中被移除:

select_query()
update_query()
insert_query()
full_query()

我们鼓励所有第三方开发人员使用Capsule DBAL和PDO连接进行所有新数据库交互。

使用Capsule

在项目文件的use块中为Laravel的数据库管理器声明一个别名来访问Capsule:

<?php

use WHMCS\Database\Capsule;

// Run queries or modify tables as you like.

查询管理器

详情查看: Laravel’s query documentation
Capsule::table(string $tableName)提供了查询管理器的访问。 使用您要查询的表的名称声明它,因为它是与该表交互的第一个参数。 查询管理器具有广泛的功能,可以执行高级选择,连接,插入,更新和删除语句。 Capsule的select调用将行返回为stdClass对象。

Capsule会转义所有输入,因此不必向传递给这些方法的变量添加转义斜杠。

所有Capsule的方法都会在失败时抛出异常。 请将Capusle调用放在try / catch块中,以便进行优雅的错误处理,并避免钩子,模块或其他自定义中的潜在致命错误。

<?php

use WHMCS\Database\Capsule;

// Print all client first names using a simple select.

/** @var stdClass $client */
foreach (Capsule::table('tblclients')->get() as $client) {
    echo $client->firstname . PHP_EOL;
}

// Rename all clients named "John Deo" to "John Doe" using an update statement.
try {
    $updatedUserCount = Capsule::table('tblclients')
        ->where('firstname', 'John')
        ->where('lastname', 'Deo')
        ->update(
            [
                'lastname' => 'Doe',
            ]
        );

    echo "Fixed {$updatedUserCount} misspelled last names.";
} catch (\Exception $e) {
    echo "I couldn't update client names. {$e->getMessage()}";
}

模式管理器

如有必要,使用Capsule::schema()方法访问架构管理器以修改表架构。 模式管理器支持创建,删除和截断表以及修改列,索引和键。

WHMCS不建议更改默认表模式结构,因为这会影响产品功能。

<?php

use WHMCS\Database\Capsule;

// Create a new table.
try {
    Capsule::schema()->create(
        'my_table',
        function ($table) {
            /** @var \Illuminate\Database\Schema\Blueprint $table */
            $table->increments('id');
            $table->string('name');
            $table->integer('serial_number');
            $table->boolean('is_required');
            $table->timestamps();
        }
    );
} catch (\Exception $e) {
    echo "Unable to create my_table: {$e->getMessage()}";
}

连接管理器

Capsule::connection()方法提供对数据库连接本身的低级访问。 使用它来启动具有自动提交和回滚的事务,或访问基础PDO连接以在DBAL之外执行手动数据库查询。 连接管理器还具有检索查询和模式管理器的方法。

<?php

use WHMCS\Database\Capsule;

// Perform potentially risky queries in a transaction for easy rollback.
try {
    Capsule::connection()->transaction(
        function ($connectionManager)
        {
            /** @var \Illuminate\Database\Connection $connectionManager */
            $connectionManager->table('my_table')->insert(
                [
                    'name' => $_POST['name'],
                    'serial_number' => $_POST['serialNumber'],
                    'is_required' => (int)(bool) $_POST['isRequired'],
                ]
            );
        }
    );
} catch (\Exception $e) {
    echo "Uh oh! Inserting didn't work, but I was able to rollback. {$e->getMessage()}";
}

PDO入门

使用连接管理器的getPdo()方法检索基础PDO连接实例。 使用PDO连接执行手动查询和高级数据库使用。

<?php

use WHMCS\Database\Capsule;

// Perform potentially risky queries in a transaction for easy rollback.
$pdo = Capsule::connection()->getPdo();
$pdo->beginTransaction();

try {
    $statement = $pdo->prepare(
        'insert into my_table (name, serial_number, is_required) values (:name, :serialNumber, :isRequired)'
    );

    $statement->execute(
        [
            ':name' => $_POST['name'],
            ':serialNumber' => $_POST['serialNumber'],
            ':isRequired' => (bool) $_POST['isRequired'],
        ]
    );

    $pdo->commit();
} catch (\Exception $e) {
    echo "Uh oh! {$e->getMessage()}";
    $pdo->rollBack();
}

排错

异常

所有Capsule方法在失败时抛出异常。 捕获这些异常并分析其消息和堆栈跟踪以帮助确定故障的性质。 WHMCS建议将所有数据库交互性放在try / catch块中,以便进行优雅的错误处理。

Capsule查询日志

连接管理器的getQueryLog()方法返回在页面请求生命期间进行的所有查询的数组。 查询作为包含查询运行的数组,传递给查询的参数绑定以及查询执行所花费的时间(以毫秒为单位)存储在日志中。

<?php

use WHMCS\Database\Capsule;

// Loop through each Capsule query made during the page request.
foreach (Capsule::connection()->getQueryLog() as $query) {
    echo "Query: {$query['query']}" . PHP_EOL;
    echo "Execution Time: {$query['time']}ms" . PHP_EOL;
    echo "Parameters: " . PHP_EOL;

    foreach ($query['bindings'] as $key => $value) {
        echo "{$key} => {$value}" . PHP_EOL;
    }
}

WHMCS活动日志

所有未捕获的基于PDO的查询失败(包括由Capsule和手动PDO查询生成的查询失败)都将写入WHMCS活动日志。 查看系统活动日志以查看这些失败查询的详细信息。

46.日志函数

以下日期助手功能可用于更轻松地使用WHMCS中的日期。

今天的日期

/**
 * Returns todays date
 *
 * By default returns the format defined in General Settings > Localisation > Date Format
 *
 * @param bool $applyClientDateFormat Set true to apply Localisation > Client Date Format
 *
 * @return string
 */
$todaysdate = getTodaysDate($applyClientDateFormat);

从MySQL取出日期

/**
 * Formats a MySQL Date/Timestamp value to system settings
 *
 * @param string $datetimestamp The MySQL Date/Timestamp value
 * @param bool $includeTime Pass true to include the time in the result
 * @param bool $applyClientDateFormat Set true to apply Localisation > Client Date Format
 *
 * @return string
 */
$date = fromMySQLDate($date, $includeTime, $applyClientDateFormat);

存入mysql 日期

/**
 * Converts a date entered in the system setting format to a MySQL Date/Timestamp
 *
 * @param string $userInputDate
 *
 * @return string Format: 2016-12-30 23:59:59
 */
$date = toMySQLDate($date);

47.货币格式

提供了以下辅助函数来格式化货币值。

获取客户的货币

/**
 * Get clients currency
 *
 * Required before making a call to formatCurrency
 *
 * @param int $userId
 *
 * @return array
 */
$currencyData = getCurrency($userId);

格式化货币

/**
 * Format currency
 *
 * @param float $amount
 * @param int   $currencyId
 *
 * @return \WHMCS\View\Formatter\Price
 */
$price = formatCurrency($amount, $currencyData['id']);

返回的$price值将是一个对象。 默认的__toString响应格式是完全格式化的价格输出,包括前缀和后缀。

查看:https://docs.whmcs.com/classes/7.1/WHMCS/View/Formatter/Price.html
获得更多信息。

原创文章,作者:赛福,如若转载,请注明出处:https://www.safecdn.cn/1266.html

本站不销售、不代购、不提供任何支持,仅分享网络信息,请自行辨别,请遵纪守法、文明上网。