codekanzlei/cake-cktools

codekanzlei 工具和实用工具集合

安装次数: 48,607

依赖项: 5

建议者: 0

安全: 0

星标: 5

关注者: 5

分支: 7

开放问题: 0

类型:cakephp-plugin


README

License Build Status

要求

安装

1. 需要插件

$ composer install codekanzlei/cake-cktools

在项目文件夹中打开终端并运行以下命令

$ composer update

3. 设置 Appcontroller.php

$helpers

public $helpers =  [
	'CkTools.CkTools'
]

用法

1. CkToolsHelper

CkTools的核心功能之一,CkToolsHelper提供了许多有用的功能,大多数功能都旨在生成强大的视图元素,如表单和导航按钮,通常只需一行代码即可。以下是其操作的概述。有关更多详细信息,请参阅CkToolsHelper.php

  • countries(array $countryCodes = null) 返回包含其翻译的国家映射。使用数组 $countryCodes 限制返回列表以满足您的需求。请参阅/cake-cktools/config/countries.php以获取国家名称的完整列表。@return array

  • country($country) 通过 $country 返回给定国家的翻译版本,例如 'en' @return string

  • function datepickerInput($field, array $options = []) 创建一个整洁的日期选择器输入字段,在编辑或添加视图中非常实用。@return string

  • mailtoLink($email, array $options = []) 为在 $email 中给出的电子邮件地址创建一个mailto链接。 $options 包含 'body''subject''caption'。@return string

  • editButton(EntityInterface $entity, array $options = []) 为给定的数据库记录 $entity 渲染一个编辑按钮。默认情况下,此按钮将链接到实体的控制器编辑操作,但可以使用 $options 数组的 'url' 字段来覆盖。@return string

  • viewButton(EntityInterface $entity, array $options = []) 为给定的数据库记录 $entity 渲染一个详情按钮。默认情况下,此按钮将链接到实体的控制器视图操作,但可以使用 $options 数组的 'url' 字段来覆盖。@return string

  • addButton($title = null, array $options = []) 为当前模型渲染一个添加按钮。例如,在 Users 索引视图文件中使用此按钮可以渲染一个创建新 User 记录的按钮。@return string

  • deleteButton(EntityInterface $entity, array $options = []) 为给定的数据库记录 $entity 渲染一个删除按钮。您可以在 $options 数组的 'confirm' 字段中定义自定义确认消息。@return string

  • formButtons(array $options = []) 渲染表单按钮“保存”和“取消”。$options 包含 'cancelButton',它控制是否渲染取消按钮,以及 'useReferer',它控制是否返回请求的引用地址。@return void

  • button($title, $url = false, array $options = []) 渲染一个按钮。通过在 '$url' 参数中传递 URL 对象来链接到所需的任何控制器动作。$options 包括 'icon'(使用 Font Awesome)、'class''additionalClasses'。使用 Twitter Bootstrap 来设置后两个选项。@return string

  • definitionList($data, array $options = []) 渲染一个 HTML 定义列表元素。参数 $data 持有键值对的数组结构。在视图文件中使用以下行来查看此动作的结果。

     <?= $this->CkTools->definitionList($this->CkTools->countries()) ?>
    

@return string

  • nestedList($data, $content, $level = 0, $isActiveCallback = null) 渲染一个嵌套列表。参数 $data 持有要显示的数据,为关联数组结构,$content 是每个节点的字符串模板。参见 CkToolsHelper.php 中的示例调用。@return string

  • historyBackButton(array $options = []) 渲染一个 div,其中包含使用浏览器历史 API 的 onclick 处理器。@return string

  • displayStructuredData(array $data, array $options = []) 以可读的格式显示数组。'$options' 数组包括一个字段 'expanded',如果设置为 true,则渲染一个按钮来切换列表的显示。@return string

  • arrayToUnorderedList(array $array) 递归地将数组转换为无序列表。@return string

2. MenuHelper

MenuHelper 旨在基于配置在 UI 中渲染分层导航菜单。以下是其动作的概述。有关更多详细信息,请参阅 MenuHelper.php

  • renderSidebarMenuItems($config) 根据给定的菜单配置创建菜单栏的 HTML 标记。配置可以以字符串的形式传递,或者你可以创建一个名为 /config/menu.php 的文件,其中包含菜单的结构。使用此配置文件来定义一个包含菜单项及其子项的 2 级菜单结构。参见 CkTools 文件夹中的 menu.php.default 作为参考。如果要在任何菜单字段中使用子项,请使用附加字段 children。如果你选择使用菜单配置文件,请在你的默认视图文件中使用以下调用:<?php echo $this->Menu->renderSidebarMenuItems('menu'); ?> @return string

  • prepareMenuConfig($config) 处理给定的菜单配置,对其进行结构化并检查权限。检查菜单项及其子项中的不允许的 URL。忽略具有字段 'shouldrender' 值为 FALSE 的菜单项。@return array

  • hasAllowedChildren(array $children) 使用 CakePHP 的 AuthComponent 检查给定的 'children' 项数组中是否至少包含一个允许当前用户访问的 URL。@return bool

  • isItemActive($item) 将当前 URL 与给定的菜单项进行比较,以确定是否应该突出显示。@return bool

config.php - 仔细查看

以下是 config.php 可能的样子,解释了更多可能性

$config = [
    'menu' => [
        'dashboard' => [            // first menu item
            'title' => 'Dashboard', // title to be displayed in the menu bar
            'icon' => 'dashboard',  // Font Awesome icon
            'url' => [              // URL object
                'plugin' => false,
                'controller' => 'Dashboard',
                'action' => 'index'
            ],
         ],
        'examples' => [             // second menu item
            'title' => 'Examples',
            'hideForRoles' => [ 	// disable rendering for certain groups
                User::ROLE_USER 	// of users
            ],
            'children' => [         // field 'children'. Note that this item
                [                   // does not have an URL object.
                    'title' => 'foo',  // first child item (menu sub-item)
                    'url' => [
                        'plugin' => false,
                        'controller' => 'Examples',
                        'action' => 'actionFoo'
                    ]
                ],
                [
                    'title' => 'bar',  // second child item (menu sub-item)
                    'url' => [
                        'plugin' => false,
                        'controller' => 'Examples',
                        'action' => 'actionBar'
                    ]
                ],
                // further sub-items for menu item 'examples'
            ]
        ],
        // further menu items

使用 CakePHP 视图创建 PDF

CkTools 包含一个用于 MPDF 库 的简单包装器。有关如何使用的详细说明,请参阅以下 GitHub 仓库:[https://github.com/mpdf/mpdf](https://github.com/mpdf/mpdf)。

用法

以下是 Cake 控制器中的示例使用,但你可以在任何地方使用此功能。有关使用的功能更详细的查看,请参阅 /cake-cktools/src/Lib/PdfGenerator.php

use CkTools\Lib\PdfGenerator;

$pdfGenerator = new PdfGenerator([
    'pdfSourceFile' => '/path/to/your/template.pdf' // optional
]);
$pdfGenerator->render('my_element', [
    'viewVars' => [
        'foo' => 'bar'
    ],
    'target' => PdfGenerator::TARGET_BROWSER,
    'cssFile' => '/path/to/your/styles.css',
    'cssStyles' => 'body { font-size: 20px }'
]);

在你的 Cake 视图文件中,你可以使用传递的 viewVars 和 $mpdf 变量来操作 PDF。

<?php $this->start('my_block') ?>
    <div class="foo"><?= $foo ?></div>
<?php $this->end() ?>

<?php
$mpdf->SetHeader('My Document Title');
$mpdf->Bookmark('Start of the document');
$mpdf->WriteHTML($this->fetch('my_block'));

// Add a new page
$mpdf->AddPage();
$mpdf->WriteHTML("This is page 2");
?>

使用 SortableBehavior 排序表格字段

CkTools 提供了一个行为,允许操作表格(显示)的记录顺序。如果你更改一个字段的顺序,行为将自动相应地更改其他所有字段的顺序。要操作位置,可以使用普通表单字段或例如 Cake 前端桥接器以启用基于 JavaScript 的拖放交互在浏览器 UI 中。

使用 StrictPasswordBehavior 实现严格的密码

通过在UsersTable中设置StrictPasswordBehavior来激活严格的密码要求;在此示例中设置了默认配置

$this->addBehavior('CkTools.StrictPassword', [ // 密码最小长度 'minPasswordLength' => 10, // 不允许在密码中使用名字和姓氏(不区分大小写) 'noUserName' => true, // 密码中至少需要一个特殊字符 'specialChars' => true, // 密码中至少需要一个大写字母 'upperCase' => true, // 密码中至少需要一个小写字母 'lowerCase' => true, // 密码中至少需要一个数字 'numericValue' => true, // 不允许重复使用旧密码:保留旧密码的数量 'oldPasswordCount' => 4 ]);

用法

将SortableBehavior添加到您想要使用的表中

public function initialize(array $config)
{
	$this->addBehavior('CkTools.Sortable', [
	    'sortField' => 'sort',
	    'columnScope' => ['mediatype_id'],
	    'defaultOrder' => ['sort' => 'ASC']
	]);
}

当前记录的'位置'将作为整数存储在字段'sort'中。您需要在您的模型中具有此字段。如果它不命名为'sort',您可以在此处相应地配置行为。

以下是在CakePHP架构中允许排序的表字段可能的样子。

'sort' => ['type' => 'integer', 'length' => 6, 'unsigned' => false, 'null' => false, 'default' => null, 'comment' => '', 'precision' => null, 'autoIncrement' => null],

使用TableUtilitiesTrait操作数据库记录

TableUtilitiesTrait包含一个操作,允许手动更新表中字段的值。使用updateField()绕过cake验证和对象的修补。给定值将直接通过SQL查询写入数据库。

设置模型

YourTable.php中添加Trait

<?php
namespace App\Model\Table;

use CkTools\Utility\TableUtilitiesTrait;

class MediaTable extends Table
{
    use TableUtilitiesTrait;
    ...

现在您可以使用updateField()操作直接操作记录。让我们更详细地看看它的参数

  • $primaryKey:您要操作的记录的主键
  • $field:您想要更改的字段名称
  • $value = null:您想要保存到数据库中的新值

使用TypeAwareTrait处理类型常量

具有类型常量的实体非常有用,例如,如果您希望对不同类型的用户授予不同的权限,例如管理员、普通用户、外部用户等。使用CkTools的TypeAwareTrait,设置和使用此类常量变得快速简单。

设置模型

让我们准备一个示例用例,您想在应用程序中将不同的角色分配给不同的用户组。将您的User.php设置如下

<?php
namespace App\Model\Entity;
use CkTools\Utility\TypeAwareTrait;

class User extends Entity
{
    use TypeAwareTrait;

	/**
	 * Define the type constants as needed as class constants.
	 */
	const ROLE_ADMIN = 'admin';
	const ROLE_USER = 'user';
	const ROLE_CUSTOMER = 'customer';
	/**
	 * (optional) Overwrite the actions in TypeAwareTrait according to your needs.
	 */

	public static function typeDescriptions()
	{
	    return [
	        self::ROLE_ADMIN => 'admin, has R+W access to all the things',
	        self::ROLE_USER => 'user, has W access to some things',
	        self::ROLE_CUSTOMER => 'external customer, has R-only access',
	    ];
	}

	public static function getRoles()
	{
	    return self::getTypeMap(
	        self::ROLE_ADMIN,
	        self::ROLE_USER,
	        self::ROLE_CUSTOMER
	    );
	}

让我们继续使用用户角色示例。以下是如何访问您的类型常量

User::getRoles()

使用此Trait可以简单地控制当前登录用户可以和不能访问的操作。您可以使用自己的方法来授予或拒绝对控制器操作的访问权限,或者简单地使用TypeAwareTrait来防止在UI中渲染操作按钮。

示例:在模型Cars的Cake视图文件中

<?php if(in_array($this->Auth->user('role'), [User::ROLE_ADMIN, User::ROLE_USER]): ?>
	<?= $car->price ?>
<?php else: ?>
	<span>Please sign up or create an account to see this</span
<?php endif; ?>

使用UserToken识别用户

CkTools提供了一个实用程序类,用于生成用于标识用户的序列化、加密和base64编码,通常用于URL中。这对于'忘记密码'链接非常方便,如果您有LoginController,建议在LoginController中使用UserToken。

用法

以下是如何在任何您喜欢的类中使用UserToken

use CkTools\Utility\UserToken;

// Use `'Configure'` to define a `'Security.cryptKey'` in your application.
// It must be at least 256 bits (32 bytes) long.
Configure::write('Security.cryptKey','<your_32_bytes_security_crypt_key>');

// Create a new instance of UserToken
$UserToken = new UserToken;

现在您可以通过$UserToken对象访问以下操作

  • getTokenForUser(User $user, $validForSeconds = null, array $additionalData = [])为给定的用户实体生成一个base64编码的令牌。使用$validForSeconds参数来确定令牌的有效期。此外,您可以在$additionalData数组中(可选地)传递其他信息。

  • isTokenExpired($token)根据给定令牌的$generated$validForSeconds属性,此方法验证令牌是否有效。

  • decryptToken($token)解密给定的令牌,允许您通过getTokenForUser()创建时传递的所有数据访问。

  • getUserIdFromToken($token)解密给定的令牌,并仅返回加密的用户_id。

有关这些操作的更多信息,请参阅cake-cktools/src/Utility/UserToken.php

国际化Shell

CkTools 提供了一个用于 i18n 相关任务的辅助 shell。

从目录更新 .po 和 .mo 文件

要自动更新从目录(.pot)文件中可用的翻译字符串的 .po/.mo 文件,请使用 updateFromCatalog 命令。

这是通过使用出色的 oscarotero/Gettext 库实现的。

用法

  1. 使用 src/Locale/default.pot 中的翻译字符串更新在 src/Locale/* 中找到的所有 default.po 和 default.mo 文件。Shell 将列出将要修改的文件,并请求确认。

     bin/cake CkTools.Internationalization updateFromCatalog
    
  2. 使用 src/Locale/default.pot 中的翻译字符串更新在 src/Locale/* 中找到的所有 default.po 和 default.mo 文件。Shell 将在不进行交互的情况下覆盖文件。

     bin/cake CkTools.Internationalization updateFromCatalog --overwrite
    
  3. 使用 src/Locale/default.pot 中的翻译字符串更新在 src/Locale/* 中找到的所有 default.po 和 default.mo 文件。Shell 将在不进行交互的情况下覆盖文件。此外,它将删除所有引用,即从结果 .po 和 .mo 文件中删除翻译所用的文件名和行号。

     bin/cake CkTools.Internationalization updateFromCatalog --overwrite --strip-references
    
  4. 使用 src/Locale/default.pot 中的翻译字符串更新在 src/Locale/* 中找到的所有 cake.po 和 cake.mo 文件。Shell 将列出将要修改的文件,并请求确认。

     bin/cake CkTools.Internationalization updateFromCatalog --domain cake
    

密码哈希器 Shell

如果您需要在本地开发数据库中更新密码,请使用此 Shell 生成哈希值。

    bin/cake CkTools.PasswordHasher <password-to-hash>

安全组件

CkTools 提供了一个组件,用于设置多个安全增强型头部。

安全头部

SecurityComponent 加载到您的 AppController 中,该组件将挂钩到 beforeFilter 事件,并默认设置

  • X-XSS-Protection 头部为 1; mode=block
  • X-Content-Type-Options 头部为 nosniff

目前这两个头部既不可配置,也无法停用,因为它们似乎在每种情况下都是合理的。

此外,您可以在 app.php 中配置多个额外的头部。

用法

以下是您的 app.php 中所有附加安全头部的完整配置示例

'CkTools' => [
    'Security' => [
        // Strict-Transport-Security header
        'HSTS' => 'max-age=31536000; includeSubDomains',

        // Content-Security-Policy, you could set a string like so
        'CSP' => "img-src 'self' blob: data:; default-src 'self' https:;"

        // or if it gets to long, as array
        'CSP' => [
            'font-src' => "'self' data:",
            'frame-ancestors' => "'self'",
            'connect-src' => "'self'",
            'img-src' => [
                "'self'",
                'blob:',
                'data:',
                'https://*.some-domain.com',
            ],
            'default-src' => [
                "'self'",
                'https:',
                'blob:'
            ]
        ],

        // bool config value to set X-Frame-Options header to "DENY" if true
        'denyFraming' => true
    ]
],

由 'denyFraming' 设置的 X-Frame-Options 头部被内容安全策略的 frame-ancestors 指令覆盖,但由于 frame-ancestors 在 IE11 和更早版本的 Edge、Safari 9.1(桌面)、Safari 9.2(iOS)中尚未支持,建议站点在使用 CSP 的同时使用 X-Frame-Options。

如果您希望排除任何头部,只需将其值设置为假值或完全省略数组键。