3xw / cakephp-attachment
CakePHP 新的附件插件
Requires
- php: >=7.2
- 3xw/cakephp-utils: ^4.0
- cakephp/cakephp: ^4.0
- firebase/php-jwt: ^5.0
- friendsofcake/crud: ^6.0
- friendsofcake/search: ^6.0
- intervention/image: ^2.3
- league/flysystem-aws-s3-v3: ^1.0
- league/flysystem-ziparchive: ^1.0
Requires (Dev)
README
附件插件解决与媒体、文件和嵌入数据相关的常见问题。目标是存储您希望存储的文件(Dropbox、AWS S3等),并在表中记录它们。
附件提供了存储层、数据库层,以及针对常见需求的前端和后端解决方案。
它使用 CakePHP 3、Flysystem 和 Intervention Image
安装
安装.composer
您可以使用 composer 将此插件安装到您的 CakePHP 应用程序中。
安装 composer 包的推荐方法是
composer require 3xw/attachment
安装.load
在 src/Application.php 中
$this->addPlugin(\ Attachment\Plugin::class, ['bootstrap' => true, 'routes' => true]);
或者,您可以使用自己的设置(config/attachment.php)覆盖
Configure::write('Trois\Attachment.config', ['attachment']); $this->addPlugin(\ Attachment\Plugin::class, ['bootstrap' => true, 'routes' => true]);
安装.db
bin/cake migrations migrate -p Trois/Attachment
sql 文件可以在路径中找到
vendor/3xw/attachment/config/Schema/attachment.sql
安装.folders
创建一个缩略图文件夹,并使用适当的 chmod 允许 php 在其中写入...
mkdir webroot/thumbnails chmod 777 webroot/thumbnails
如果您在本地存储文件,则创建一个文件夹,根据默认设置或您自己的设置。默认设置如下
mkdir webroot/files chmod 777 webroot/files
后端依赖项
后端依赖项.libs
为了使用后端工具,您需要安装以下库
javascript
jquery >= 1.x
vuejs = 2.x
vue-resource = 1.x
css
bootstrap = 4.x
后端依赖项.html
Vuejs 组件被嵌套到一个顶层父组件中,您需要设置。它需要一个额外的块(模板)。以下是如何轻松实现的。
在您的 layout.ctp 中
<head> ... <!-- CSS --> <?= $this->Html->css([ 'bootstrap.min.css', 'app.css' ]) ?> <?= $this->fetch('css') ?> ... </head> <body> <div id="admin-app" class="wrapper"> ...flash, content goes here... </div> <!-- TEMPLATES --> <?= $this->fetch('template') ?> <!-- SCRIPTS --> <?= $this->Html->script([ 'jquery.min.js' 'vue.min.js', 'vue-resource.min.js', 'app.js' ]) ?> <?= $this->fetch('script') ?> </body>
后端依赖项.js
在您的 app.js 中
(function(scope, $, Vue){ // boostrap $(document).ready(function(){ var adminApp = new Vue({el: "#admin-app"}) }) })(window, jQuery, Vue)
设置
默认设置位于以下路径:vendor/3xw/attachment/config/attachment.php
您可以在以下路径创建自己的设置:config/attachment.php
设置示例
return [ 'Attachment' => [ // set profiles 'profiles' => [ 's3' => [ 'replace' => false, 'afterReplace' => null // null | callback fct($entity), 'delete' => true, 'adapter' => 'League\Flysystem\AwsS3v3\AwsS3Adapter', 'client' => new League\Flysystem\AwsS3v3\AwsS3Adapter(Aws\S3\S3Client::factory([ 'credentials' => [ 'key' => '***', 'secret' => '***', ], 'region' => 'eu-central-1', 'version' => 'latest', ]),'s3.example.com',''), 'baseUrl' => 's3.example.com' ], ], // lsiteners lsiteners => [], // upload settings 'upload' => [ 'maxsize' => 30, // 30MB 'types' =>['image/jpeg','image/png','image/gif'], 'atags' => [], 'atagsDisplay' => false, // false | 'select' | 'input' 'profile' => 's3', // pagination setting in browse views 'pagination' => [ 'offset' => 9, // = 10 pages 'start' => true, 'end' => true, ], ], // thumbnails settings 'thumbnails' => [ 'driver' => 'Imagick', // or Imagick if installed, 'compression' => [ 'jpegoptim' => '/usr/local/bin/jpegoptim', // path or false ( default /usr/local/bin/jpegoptim ) 'pngquant' => '/usr/local/bin/pngquant', // path or false ( default /usr/local/bin/pngquant ) 'quality' => 25 // encoding quality level from 0 to 100 ( default 25 ) ], 'breakpoints' => [ 'lg' => '(min-width: 1200px)', 'md' => '(max-width: 1199px)', 'sm' => '(max-width: 991px)', 'xs' => '(max-width: 767px)', ], 'widths' => ['678','1200'], 'heights' => false, 'aligns' => false, // or some of following [0,1,2,3,4,5,6,7,8] with 0 center, 1 top, 4 left, 5 right top corner, 8 left top corner .... 'crops' => ['16:9','4:3','1:1'] ] ]];
设置.profiles
您可以根据 Flysystem 文档设置您的配置文件,只需添加 baseUrl 以获取完整的 URL。配置文件按名称存储。因此,您可以将文件分割到多个系统中。
附件附带三个默认配置
default // Local file system stored in webroot/files
external // used for external urls
cache // for thumbs creations
以下是本地存储的默认适配器
'default' => [ 'adapter' => 'League\Flysystem\Adapter\Local', 'client' => new League\Flysystem\Adapter\Local('files'), 'baseUrl' => '/files/' ],
因此,您可以使用自己的或通过 composer 安装新的适配器。
设置.upload
上传在保存相关记录之前进行。全局设置在 Attachment.upload 下设置。您可以在全局行为中设置,然后在 add.ctp 或 edit.ctp 中覆盖它们。这里有几个选项
'upload' => [ 'maxsize' => 30, // 30MB 'types' =>['image/jpeg','embed/soundcloud',...], // mime types and embed/:service for embed stuff 'atags' => [], // atags are use to store attachemnts with 'relation' => 'belongsToMany', // model relation 'profile' => 'default', // profile to use (where you store files) 'visibility' => 'public', // public or private 'speech' => false, // french goody 'restrictions' => [] // or Trois\Attachment\View\Helper\AttachmentHelper::TAG_RESTRICTED ],
限制是在后端用于排序文件的属性
AttachmentHelper::TAG_RESTRICTED // enforce attachments to associted with given tags in save and retieve with a AND strategy AttachmentHelper::TAG_OR_RESTRICTED // enforce attachments to associted with given tags in save and retieve with a OR strategy AttachmentHelper::types_restricted // enforce attachments to saved and retrieve with a OR strategy according given mime types
设置.listeners
监听器是执行相关事件触发时执行的事件处理器。您可以在附件配置文件中设置通用目的的处理程序,或者您可以在具有 CRUD 功能的任何附件辅助函数的设置数组中添加 'listeners' 键。
'listeners' => [ 'beforePaginate' => [ 'App\Listener\MyListener', 'App\Listener\MayOtherListener' => [ 'momo' => 'toto' ] ], ]
触发事件列表是
beforeFilter startup beforeDelete afterDelete beforeFind afterFind beforeSave afterSave beforePaginate afterPaginate beforeRedirect beforeRender recordNotFound setFlash
监听器应扩展 BaseListener 类
namespace App\Listener; use Trois\Attachment\Listener\BaseListener; use Cake\Event\Event; class ExtranetMoveFileListener extends BaseListener { // $event->getSubject() returns an object with minimum a request variable // all model events are wrapped on top of: // https://crud.readthedocs.io/en/latest/events.html#crud-beforesave public function respond(Event $event) { } }
设置.thumbnails
Attachment.thumbnails 是生成缩略图的设置。
'thumbnails' => [ 'driver' => 'Imagick', // or Imagick if installed, 'widths' => [600, 1200], 'heights' => [], 'aligns' => [], // or some of following [0,1,2,3,4,5,6,7,8] with 0 center, 1 top, 4 left, 5 right top corner, 8 left top corner .... 'crops' => ['4:3','16:9'] ]
这些设置是全局的,并限制局部更改,以保持缩略图逻辑在一个文件中并限制额外格式。每个表都是允许的可能性。因此,只允许 600px 和 1200px 的缩略图。只允许 4:3 和 16:9 的裁剪。
用法
用法.model
附件包含两个表格:附件和Atags。因此,您可以绑定您任何模型,所有关系类型都受到支持。
$this->belongsToMany('Attachments', [ 'foreignKey' => 'post_id', 'targetForeignKey' => 'attachment_id', 'joinTable' => 'attachments_posts' ]); // OR $this->belongsTo('Attachments', [ 'foreignKey' => 'attachment_id', 'joinType' => 'INNER' // OR LEFT ... ]);
附件还处理一个'order'字段。因此,您可以在您自己的HABTM连接表中自由添加此类字段...
使用.controller
只需使用包含或您需要的任何连接...
public function index() { $this->paginate = [ 'contain' => ['Attachments' /* => ['sort' => 'order'] */ ] // if HABTM with an order field ]; $posts = $this->paginate($this->Posts); $this->set(compact('posts')); $this->set('_serialize', ['posts']); }
使用.view
所有技能都在Helper Attachment中。所以首先将其添加到您的AppView。
在src/View/AppView.php中
public function initialize() { $this->loadHelper('Trois/Attachment.Attachment'); }
使用.view.backend
在add.ctp中
<!-- Attachment --> <?= $this->Attachment->input('Attachments', // if Attachments => HABTM else if !Attachments => belongsTo [ 'label' => 'Image', 'types' =>['image/jpeg','image/png'], 'atags' => ['Restricted Tag 1', 'Restricted Tag 2'], 'profile' => 's3', // optional as it was set in config/attachment.php 'cols' => 'col-xs-6 col-md-6 col-lg-4', // optional as it was set in config/attachment.php, 'maxquantity' => -1, 'restrictions' => [ Trois\Attachment\View\Helper\AttachmentHelper::TAG_RESTRICTED, Trois\Attachment\View\Helper\AttachmentHelper::TYPES_RESTRICTED ], 'attachments' => [] // array of exisiting Attachment entities ( HABTM ) or [entity] ( belongsTo ) ] ) ?>
在edit.ctp中
<!-- Attachment --> <?= $this->Attachment->input('Attachments', // if Attachments => HABTM else if !Attachments => belongsTo [ 'label' => 'Image', 'types' =>['image/jpeg','image/png'], 'atags' => ['Restricted Tag 1', 'Restricted Tag 2'], 'profile' => 's3', // optional as it was set in config/attachment.php 'cols' => 'col-xs-6 col-md-6 col-lg-4', // optional as it was set in config/attachment.php, 'maxquantity' => -1, 'restrictions' => [ Trois\Attachment\View\Helper\AttachmentHelper::TAG_RESTRICTED, Trois\Attachment\View\Helper\AttachmentHelper::TYPES_RESTRICTED ], 'attachments' => $posts->attachments // array of exisiting Attachment entities ( HABTM ) or entity ( belongsTo ) ] ) ?>
全局附件索引
<!-- Attachments element --> <?= $this->Attachment->buildIndex([ 'actions' => ['add','edit','delete','view','download'], 'types' =>['image/jpeg','image/png','embed/youtube','embed/vimeo'], 'atags' => ['Restricted Tag 1', 'Restricted Tag 2'], 'listStyle' => true, 'profile' => 's3', // optional as it was set in config/attachment.php 'restrictions' => [ Trois\Attachment\View\Helper\AttachmentHelper::TAG_RESTRICTED, Trois\Attachment\View\Helper\AttachmentHelper::TYPES_RESTRICTED ] ]) ?>
TinyMCE 插件
附件附带一个TinyMCE插件。与包cakephp-tinymce一起工作
echo $this->element('Trois/Tinymce.tinymce',[ 'field' => 'content', 'value' => $post->content, 'init' => [ 'external_plugins' => [ 'attachment' => $this->Url->build('/attachment/js/Plugins/tinymce/plugin.min.js', true), ], 'attachment_settings' => $this->Attachment->jsSetup('content',[ // overrides config/attachment.php settings 'types' => [ 'application/pdf', 'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'image/jpeg', 'image/png', 'embed/youtube', 'embed/vimeo' ], 'thumbBaseUrl' => '', //IF NOT $this->Url->build('/') 'atags' => [], 'restrictions' => [ Trois\Attachment\View\Helper\AttachmentHelper::TAG_OR_RESTRICTED, Trois\Attachment\View\Helper\AttachmentHelper::TYPES_RESTRICTED ], ]) ] ]);
这将让您直接在trumbowyg文本区域中插入图像!!! 嘿嘿!
在locale.ctp中的示例
$this->element('locale',['fields' => ['meta', 'header' => [ 'Trois/Tinymce.tinymce' => [ 'value' => $post, 'init' => [] ] ], 'body' => [ 'Trois/Tinymce.tinymce' => [ 'value' => $post, 'init' => [ 'external_plugins' => [ 'attachment' => $this->Url->build('/attachment/js/Plugins/tinymce/plugin.min.js', true), ], 'attachment_settings' => [ 'types' => [ 'application/pdf', 'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'image/jpeg', 'image/png', 'embed/youtube', 'embed/vimeo' ], 'atags' => [], 'restrictions' => [ Trois\Attachment\View\Helper\AttachmentHelper::TAG_OR_RESTRICTED, Trois\Attachment\View\Helper\AttachmentHelper::TYPES_RESTRICTED ], ] ] ] ] ], 'labels' => ['meta (description google, facebook)', 'lead', 'text']]);
使用.view.frontend
在文件中
<!-- Display a 16:9 croped image --> <?= $this->Attachment->image([ 'image' => $post->attachments[0]->path, 'profile' => $post->attachments[0]->profile, 'width' => '600', 'cropratio' => '16:9, 'quality' => 50, // from 0 to 100 ( default 25 in plugin's config file attachment.php ) 'srcset' => [ 'lg' => [360,720], 'md' => [293, 586], 'sm' => [283, 566], 'xs' => [767,1534], ] ],['class' => 'img-responsive']) ?> <!-- Display an embed video --> <?= $post->attachments[0]->embed ?>
仅URL
<?= $this->Attachment->thumbSrc([ 'image' => $post->attachments[0]->path, 'profile' => $post->attachments[0]->profile, 'width' => '600', 'cropratio' => '16:9, 'quality' => 50, // from 0 to 100 ( default 25 in plugin's config file attachment.php ) 'srcset' => [ 'lg' => [360,720], 'md' => [293, 586], 'sm' => [283, 566], 'xs' => [767,1534], ] ]) ?>
使用.view.download
echo $this->Attachment->downloadLink($attachment ); // Attachment $attachment // return the full download url for THIS SESSION ONLY
使用.shell
- Attachment插件提供了一个有用的shell脚本,用于检索图像的宽度和高度
bin/cake Attachment.GetImageSizes
- 为区域创建缺少的附件翻译
bin/cake CreateMissingTranslations en_GB de_CH ...