globalis / puppet-skilled-sandbox
Puppet Skilled sandbox,基于CodeIgniter 3 PHP框架
Requires
- php: >=5.6
- globalis/puppet-skilled-framework: ^0.2.4
Requires (Dev)
- fzaninotto/faker: ^1.6
- globalis/robo-task: ^1.0
- henrikbjorn/lurker: ^1.2
- robmorgan/phinx: ^0.9.2
This package is auto-updated.
Last update: 2024-08-29 03:58:14 UTC
README
概述
Puppet Skilled是一个基于CodeIgniter的PHP框架。它为原始框架添加了一些功能
此沙盒展示了如何通过Puppet Skilled分步构建一个简单应用程序。此存储库的每个分支都向应用程序添加了以下新功能
- 步骤 1 : 基本架构,包含一个简单的静态页面,以展示Puppet Skilled的主要原则。
- 步骤 2 : 认证模块。
- 步骤 3 : 编辑个人资料和语言选择。
- 步骤 4 : 联系人列表。
- 步骤 5 : 用户和公司后台。
先决条件
在尝试使用Puppet Skilled之前,以下是一些可能有用的工具
- Git,
- Composer,
- CodeIgniter,
- Robo(特别是Globalis Robo Tasks)。
通用
安装
在安装之前,不要忘记创建数据库,然后运行
composer install
./vendor/bin/robo install
(注意:您可以通过创建别名来使用robo
而不是./vendor/bin/robo
。)
Robo将要求您输入一些信息,以构建位于.robo/build
中的配置文件
config.php
:设置环境常量,以及systems
、application
和views
路径phinx.php
:Phinx的配置文件(见步骤2中的迁移)application/config/config.php
:应用程序的主要配置文件application/config/database.php
:数据库配置application/config/email.php
:电子邮件配置
Robo问题定义在.robo/config/properties.php
中,答案存储在.robo/config/my.config
中。
步骤 1
此步骤为应用程序提供一个基本架构,包含一个用于展示Puppet Skilled主要原则的单个静态页面。
配置
应用程序配置与CodeIgniter相同。配置文件位于application/config
。
PuppetSkilled在此文件夹中添加了几个文件
site_settings.php
:定义应用程序的名称和标题,以及可用的不同语言和自动加载的lang文件
$config['site_settings'] = [ 'name' => 'Puppet Skilled', // Site name 'title' => 'Puppet Skilled', // Default page title 'multilingual' => [ // Multilingual settings (set empty array to disable this) 'default' => 'fr', 'available' => [ 'en' => [ 'label' => 'EN', // label to be displayed on language switcher 'value' => 'english', // to match with CodeIgniter folders inside application/language/ 'local' => ['en_US.UTF8', 'en.UTF8'], ], 'fr' => [ 'label' => 'FR', 'value' => 'french', 'local' => ['fr_FR.UTF8', 'fr.UTF8'], ] ], 'autoload' => ['general'], // Autoloads general_lang.php language file ], ];
template.php
:定义每个布局可自动加载的脚本和样式,以及包含资产的各个文件夹
$config['default'] = $config['empty'] = $config['simple'] = [ "style_autoload" => [ 'main', // Autoloads main.css ], "script_autoload" => [ 'vendor', // Autoloads vendor.js 'main' // Autoloads main.js ], 'html_style_path' => 'public/styles', // CSS path 'html_script_path' => 'public/scripts', // JS path 'html_image_path' => 'public/images', // Images path ];
控制器
控制器是扩展\Globalis\PuppetSkilled\Controller\Base
的类,位于application/controllers
文件夹中。它们可以像CodeIgniter控制器一样使用。
目前,定义了两个控制器
Welcome.php
:一个非常简单的控制器,只有一个index
方法Miscellaneous.php
:处理404错误的控制器。
视图
关于视图层,Puppet Skilled与CakePHP类似:它分为四个部分,每个部分代表application/views
中的一个文件夹。
- 布局:表示视图周围的展示代码(例如头部和底部)。使用的布局由控制器中的
$layout
属性定义。在本项目中,您将找到三种不同的布局simple.php
:极其简单的布局,由简单的头部和页面内容组成。empty.php
:简单的布局,用于不需要身份验证的页面。default.php
:完整的布局,当用户登录时显示导航。
- 模板:视图的主要部分,通常与单个操作相关联。在以下示例中,将自动调用
my_controller/action.php
模板,该模板由render()
方法调用。
class MyController extends \Globalis\PuppetSkilled\Controller\Base { public function action() { $this->render(); } }
此方法接受两个可选参数:一个包含要发送到视图的数据的数组,以及您想要调用的模板,该模板将自动包含在布局中。
- 块:块只是特定的模板,可重用并在其他模板中包含。您可以在视图中使用
$this->block($filename)
包含一个块。 - 单元:由微型控制器处理的视图,完全独立于任何其他视图或任何其他控制器。它们可以通过在视图中调用
$this->cell('Controller::method')
来使用。在本项目中,您将找到三个单元- DebugBar:Puppet Skilled的调试栏。
- Flash:在用户操作后显示错误和成功警报。
- 导航:显示应用程序的不同导航链接。
- 元素:小而可重用的视图(例如表单输入)。您可以使用
$this->element('element/path')
在视图中包含它们。
当使用block
和element
方法时,您可以添加一个数组作为参数,以将数据发送到块或元素,并在视图中使用$this->fetch('key')
检索它。例如,创建一个如下所示的输入元素
$this->element('form/block_input', [ 'input_element' => 'form/input', 'label' => 'lang:general_label_search', 'name' => 'search', ] );
在每一个视图中,语言使用CodeIgniter 语言类外部化。
调试栏
Puppet Skilled为开发人员提供调试栏,使用CodeIgniter的性能分析器和基准库。性能分析器库在application/library/APP_Profiler.php
中扩展,调试栏单元在application/views/Cell
中。
调试栏显示在页面顶部(点击小红虫时会展开),并提供访问有用信息的途径
- 执行时间,
- 内存使用,
- GET、POST和SESSION变量,
- 配置变量,
- HTTP头部,
- SQL请求。
您可以通过在调用控制器中的render
方法之前添加$this->output->enable_profiler(true)
来激活它。
步骤 2
这一相当重要的步骤向应用程序添加了几个功能
- 服务和库的定义,
- 数据库创建和填充,
- 一个完整的认证模块添加到应用程序,包括登录、注销、密码设置和密码重置。
架构也略有修改,在application/core
中添加了一个Base控制器,用于初始化语言、访问控制、闪存消息或调试栏激活。
依赖注入容器
Puppet Skilled使用Pimple来管理应用程序的依赖关系。容器位于application/hooks/PuppetSkilledBootstrap.php
中,并由application/config/hooks.php
中的pre_controller
钩子在CodeIgniter中调用。
$hook['pre_controller'] = [ 'class' => 'PuppetSkilledBootstrap', 'function' => 'boot', 'filename' => 'PuppetSkilledBootstrap.php', 'filepath' => 'hooks', ];
您可以根据需要如下定义不同的服务
use \Globalis\PuppetSkilled\Core\Application; class PuppetSkilledBootstrap { public function boot() { $application = Application::getInstance(); $container = $application->getContainer(); $container['serviceName'] = function () { return new App\Service\ServiceClass(); }; } }
服务随后可通过控制器中的app()->serviceName
或$this->serviceName
在整个应用程序中访问。
一些服务在Puppet Skilled中可用且可立即使用。
- 认证服务:
\Globalis\PuppetSkilled\Auth\Authentication
, - 设置服务:
\Globalis\PuppetSkilled\Settings\Settings
, - 队列服务:
\Globalis\PuppetSkilled\Queue\Service
.
以下几节将描述这些服务。
此文件还加载了会话库和ORM。
模型和ORM
Puppet Skilled的模型层扩展了Laravel使用的ORM Eloquent。要创建一个模型,只需编写一个扩展Globalis\PuppetSkilled\Database\Magic\Model
的类。
Puppet还为您提供了向模型添加一些有用特性的可能。
\Globalis\PuppetSkilled\Database\Magic\Uuid
:将模型键设置为UUID字符串。\Globalis\PuppetSkilled\Database\Magic\SoftDeletes
:在调用$model->delete()
时使用deleted_at字段而不是真正从数据库中删除实体。别忘了将此字段添加到您的数据库结构中。\Globalis\PuppetSkilled\Database\Magic\Lock\Lockable
:实体锁定以防止同时交互。使用$entity->acquireLock()
锁定您的实体,如果它已被另一个用户锁定,则返回false。修改完成后,通过调用$entity->releaseLock()
释放锁。锁在模型lockDefaultTime
属性定义的延迟后自动销毁,如果没有定义,则为150秒。\Globalis\PuppetSkilled\Database\Magic\Revisionable\Revisionable
:在修订表中记录实体所做的每个更改的历史。您可能想向模型添加一个$nonRevisionable
属性,包含所有修改不会导致新修订的字段(created_at、updated_at、deleted_at)。
迁移
Puppet Skilled使用Phinx处理数据库结构的更改,并且已经配置了Robo任务来使用它。
- 创建迁移:
robo migrate:create NameInCamelCase
,迁移文件在migrations/
中创建。 - 运行迁移:
robo migrate:up
- 回滚迁移:
robo migrate:down
您还可以创建和运行种子以在数据库中插入数据。
- 创建种子:
robo seed:create SeedName
,SeedName.php
文件在seeds/
中创建。 - 运行种子:
robo seed:run [SeedName]
执行robo seed:run
以创建一个公司和三个用户。
在编写种子时,Faker库可能很有用。
认证
认证模块基于\Globalis\PuppetSkilled\Auth\Authentication
服务构建。
- 权限:权限由树定义。如果用户访问权限高于当前检查的权限级别,则授予访问权限。例如,如果用户有后台办公室权限,他也拥有任何backoffice.*权限。
- 资源:资源使用户能够访问实体。扩展
\Globalis\PuppetSkilled\Auth\Resource
。 - 角色:角色是一组权限和资源。如果一个角色没有链接到任何资源,我们认为它有权访问所有资源。
在我们的案例中
在项目种子中定义了三个用户和一个公司
- Michel用户:与Globalis Media Systems公司关联的用户,
- Michel经理:与Globalis Media Systems公司关联的经理,
- Michel管理员:管理员。
您可以通过控制器中的$guards
属性来处理控制器和方法访问。此数组由Base控制器的secureAccess
方法使用。例如
protected $guards = [ 'index' => 'backoffice.user.view', 'add' => 'backoffice.user.edit', 'edit' => 'backoffice.user.edit', 'delete' => 'backoffice.user.edit', ];
这样,具有 backoffice.user 权限的用户将能够访问所有方法,而具有 backoffice.user.view 权限的用户只能访问 index
。
此服务还提供了一些有用的方法
app()->authenticationService->isLoggedIn()
:检查用户是否已认证。app()->authenticationService->user()
:返回当前已认证的用户。app()->authenticationService->userCan($permission, $resourceType, $resourceValue)
:检查已认证用户是否有权访问特定资源(如果资源参数为空,则为全局权限)。- 登录、登出、密码设置和重置方法:更多详情请参阅
vendor/globalis/puppet-skilled-framework/src/Auth/Authentication.php
。
会话由自定义会话驱动程序处理,该驱动程序扩展了 CodeIgniter 驱动。该驱动程序将会话存储到数据库的 sessions
表中。它通过 config/config.php
文件中的 sess_*
参数进行配置。
设置
在 \Globalis\PuppetSkilled\Settings\Settings
中提供了设置服务,它允许您从数据库中检索应用程序的全局参数。设置定义为简单的键值结构,还有一个额外的 autoload
字段。
此服务使用 settings
表,其使用方法相当简单
app()->settings->get($key)
:从数据库中检索设置。app()->settings->update($key, $value)
:将设置的值更改为$value
。
队列
发送邮件等任务可以通过作业队列来处理。在 \Globalis\PuppetSkilled\Queue\Service
中提供了队列服务。作业在扩展 \Globalis\PuppetSkilled\Queue\Queueable
的类中定义。作业按以下方式放入队列
app()->queueService->dispatch($job);
要执行队列中的作业,请在项目根目录下执行以下命令
php index.php queue
在 app/jobs
中提供了一个可队列的 App\Jobs\Mailer
类,它使用 CodeIgniter 邮件类。
步骤 3
此步骤添加了一个简单的表单,允许用户编辑其个人信息,使用 CodeIgniter 表单验证类。
自定义服务
此步骤提供了一个语言服务,允许用户在英语和法语之间切换。您可以通过以下方式创建自己的服务:扩展 Puppet Skilled 服务类
namespace App\Service; class Language extends \Globalis\PuppetSkilled\Service\Base { }
只需在 application/hooks/PuppetSkilledBootstrap.php
中注入此服务
$container['languageService'] = function ($c) { return new \App\Service\Language(); };
现在您可以通过调用 app()->languageService
一样使用它,就像使用其他任何服务一样。
助手
框架在其核心中定义了一些有用的函数:请参阅文件 /vendor/globalis/puppet-skilled-framework/src/Core/helpers.php
。它包含帮助开发者处理数组、字符串或我们之前使用的 app()
函数的函数。
此外,在 application/helpers
文件夹中,您可以找到一些“扩展”多个 CodeIgniter 原生助手 的文件。我们扩展了日期、表单、语言和 URL 助手,以改进一些功能并添加其他功能。
APP_date_helper.php
使用了出色的 Carbon 库,它扩展了 PHP 的 DateTime 类,提供了有用的日期格式化函数。APP_form_helper.php
替换了form_open
并添加了处理必填字段的函数。APP_language_helper.php
添加了lang_libelle
函数,该函数包装了原始的lang
函数。APP_url_helper.php
创建了帮助处理 URL 的函数(创建链接、重定向等)。
打开这些文件以查看它们提供的功能和精确用法。您也可以定义自己的辅助程序 - 请参阅CodeIgniter 文档。
步骤 4
此步骤添加了一个联系人列表模块,列出平台上的用户。它使用了两个 Puppet Skilled 库
QueryFilter
此库位于 \Globalis\PuppetSkilled\Library\QueryFilter
,使开发者能够快速在 SELECT 请求上创建用户过滤器,例如显示属于特定公司的用户。
$filters = new QueryFilter( [ 'filters' => [ // Filter definitions using closures 'last_name' => function($query, $value) { return $query ->where('last_name', 'like', $value . '%'); }, ], 'save' => 'frontoffice_contact_filters', // Key for session storage or false 'method' => 'get', // Method used by the form 'action' => 'action', // Key of the POST/GET variable 'filter_action' => 'filter', // Value of the variable to apply the filters 'reset_action' => 'reset', // Value of the variable to clear the filters 'default_filters' => [ // Default value for the filters 'last_name' => 'Default value', ], ] );
使用 $filters->run(Model::query())
来运行过滤器并将 $filters
发送到您的视图,在视图中创建一个具有名为 last_name
的输入字段的表单,并使用 QueryFilter 对象的这些方法:
getActionName()
: 表单发送的 POST/GET 变量的键,getResetActionValue()
: 提交按钮的名称,getFilterActionValue()
:重置按钮的名称。
QueryPager
此库位于 \Globalis\PuppetSkilled\Library\QueryPager
,使开发者能够快速在 SELECT 请求上设置分页和排序。
$pager = new QueryPager( [ 'limit_choices' => [10, 20, 50], // Items per page choices 'limit' => 10, // Items per page by default 'sort' => [ // Sortable columns 'last_name' => 'last_name', 'email' => 'email', ], 'save' => 'frontoffice_contact_pager', // Key for session storage 'unique_order_key' => Model::query() // Unique key for ordering or false ->getModel() ->getKeyName(), 'page' => 1, // Default page number 'request_param' => [ // Available parameters to organise the results 'page' => 'page', 'order' => 'order', 'direction' => 'direction', 'limit' => 'pagesize' ], ] );
使用 $pager->run(Model::query())
来运行分页器并将其发送到您的视图,在视图中您可以使用以下方法:
getResult()
: 返回一个具有以下键的数组
[ 'result', // Result of the SQL query 'page', // Current page 'total', // Total number of elements 'perPage', // Elements per page 'prevPage', // True if a previous page exists 'nextPage', // True if a next page exists 'pageCount', // Number of pages 'sort', // Columned used to order the results 'direction', // Direction of the ordering (asc/desc) 'limit', // Limit 'limit_choices' // Available limit choices ]
isSortable($fieldName)
: 检查列$fieldName
是否可排序。
为了对结果进行排序,使用两个 GET 参数:用于字段名称的 order
和用于升序或降序排序的 direction
(asc
或 desc
)。
已经提供了 CRUD 元素,以便使用您的过滤器和分页器,或者您也可以编写自己的。请参阅 application/controllers/frontoffice/Contact.php
中的精确用法,相应的视图在 application/views/frontoffice/contact/
中,以及 CRUD 元素在 application/views/Element/crud/
中。
步骤 5
此步骤向应用程序中添加了一个后台办公室模块,以便编辑公司和用户。两个页面 backoffice/company
和 backoffice/user
允许用户编辑、添加和删除公司和用户。
管理员可以访问这两个页面,而经理只能访问最新页面。普通用户则完全无法访问后台办公室。
此外,经理只能编辑和添加属于他们自己的公司的用户。
为了简化访问控制,认证服务已经扩展,以便我们可以添加一个方法来检查用户是否可以编辑另一个用户实体。