Top Banner
1
60

XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

Apr 16, 2017

Download

Software

XpressEngine
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

1

Page 2: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

오승훈 @akasima

• XE 커뮤니티 개발 그룹

• XE3 개발

• Database, Document, DynamicField, Presenter..

• XE3 게시판 플러그인 개발

2

Page 3: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

목차

33

플러그인 제작

플러그인 생성 관리자 사이트맵에서 메뉴 생성 라우트 등록

인터셉션

데이터 베이스

Page 4: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

Manual 플러그인

4

Page 5: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

Manual 플러그인 요구사항

5

카테고리 도큐먼트

Page 6: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

관리자 > 사이트맵에서 메뉴 생성

6

Page 7: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

플러그인 생성

7

Page 8: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

플러그인 규칙

디렉토리이름은 소문자, 숫자와 언더스코어(언더바)로 작성 plugin.php, composer.json 필수

8

Page 9: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

plugin.php - 필수 요소1

9

<?phpnamespace Akasima; use …; class Plugin extends AbstractPlugin{ /** * 이 메소드는 활성화(activate) 된 플러그인이 부트될 때 항상 실행됩니다. * * @return void */ public function boot() { }

Page 10: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

AbstractPlugin

10

http://api.xpressengine.io

Page 11: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

11

플러그인 코어 패키지플러그인

플러그인 코어 패키지는 플러그인에게 묻고 싶은게 많습니다.

Page 12: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

12

<?phpabstract class AbstractPlugin{ public static function getId() public static function getIdWith($postfix = '', $delimiter = '::')

public function activate($installedVersion = null) public function deactivate($installedVersion = null) public function install() public function checkInstall($installedVersion = null) public function update($installedVersion = null) public function checkUpdate($currentVersion = null) public function uninstall() abstract public function boot(); public function getSettingsURI() public static function getPath($path = '') public static function asset($path, $secure =

Page 13: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

composer.json - 필수 요소2

13

{ "name": "xpressengine-plugin/my_plugin", "description": "플러그인소개", "keywords": [ "xpressengine", "plugin" ], "license": "LGPL-2.0", "version": "1.0.0", "type": "xpressengine-plugin", "support": { "email": "[email protected]" }, "authors": [ { "name": "input your name", "email": "[email protected]", "homepage": "http://mysite.com", "role": "Developer" } ],

"extra": { "xpressengine": { "title": "my_plugin_title", "icon": "myicon.png", "component": [] } }, "repositories": [ { "type": "composer", "url": "http://packagist.xpressengine.io/" } ], "require": { }, "autoload": { "psr-4": { "Akasima\\": "src/" } }}

app/Console/Commands/stubs/composer.json.stub 복사

Page 14: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

플러그인 생성 완료

14

composer.json

pluing.php

Page 15: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

플러그인 생성 확인

15

Page 16: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

플러그인 켜기

16

Page 17: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

플러그인 동작 확인

17

public function boot(){ $this->route(); } protected function route(){ // implement code Route::fixed($this->getId(), function () { Route::get('/', [ 'as' => 'my_plugin::index', 'uses' => function (Request $request) { echo "Hello World"; } ]); }); }

Page 18: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

어렵다!!

Page 19: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

간단한 command 제공

19

php artisan make:plugin my_plugin Akasima my_plugin_title

Page 20: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

20

vendor

view

생성된 디렉토리

assets

src

composer.json

pluing.php

js, css, imagePHP source

템플릿

Page 21: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

21

메뉴 추가

Page 22: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

22

컴포넌트?

my_plugin

테마 스킨 매뉴얼

위젯 게시판 스킨

플러그인은 설치/실행 등 기능 꾸러미 관리의 목적

플러그인은 여러개의 기능 요소로 이루어짐

(컴포넌트가 있을 수 있음)

Page 23: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

23

컴포넌트

Interface XE3

Module\AbstractModule 모듈

Skin\AbstractSkin 스킨

Theme\AbstractTheme 테마

Widget\AbstractWidget 위젯

UIObject\AbstractUIObject UI Object

DynamicField\AbstractType FieldType

DynamicField\AbstractSkin FieldSkin

Page 24: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

24

ComponentInterface

Page 25: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

25

ComponentInterface

Page 26: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

26

컴포넌트 ID

플러그인 코어 패키지

my_plu

테마 스킨 매뉴

위젯 게시판

저 등록좀 해주세요~ 그리고 저 한테 컴포넌트도 있으니까 이 애들도 등록할께요

Page 27: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

27

컴포넌트 ID

플러그인 코어 패키지

my_plu

테마 스킨 매뉴

위젯 게시판

저 등록좀 해주세요~ 그리고 저 한테 컴포넌트도 있으니까 이 애들도 등록할께요플러그인 코어 패키지

컴포넌트

Page 28: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

28

컴포넌트 ID

플러그인 코어 패키지

my_plu

테마 스킨 매뉴

위젯 게시판

Register 코어 패키지에 컴포넌트 등록

Page 29: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

29

컴포넌트 ID

등록된 컴포넌트 리스트

Page 30: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

컴포넌트 ID란?

module/board@board

module/my_plugin@manual

컴포넌트종류/플러그인@컴포넌트이름

Page 31: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

컴포넌트 ID

module/board@board

module/my_plugin@manual

// my_plugin 에서 등록한 게시판 모듈용 redSkin module/board@board/skin/my_plugin@redSkin

// my_plugin 에서 등록한 매뉴얼 모듈용 redSkin module/my_plugin@manual@skin/my_plugin@blueSkin

컴포넌트종류/플러그인@컴포넌트이름/컴포넌트종류/플러그인@컴포넌트이름

대상아이디/컴포넌트종류/플러그인@컴포넌트이름

Page 32: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

32

src/Manual.php

<?phpnamespace Akasima; use Xpressengine\Module\AbstractModule; class Manual extends AbstractModule{ public static function getInstanceSettingURI($instanceId) { } public function createMenuForm() { } public function storeMenu($instanceId, $menuTypeParams, $itemParams) { } public function editMenuForm($instanceId) {

Page 33: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

33

MenuTypeInterface

Page 34: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

34

Composer.json - 컴포넌트 등록

"extra": { "xpressengine": { "title": "my_plugin_title", "icon": "myicon.png", "component": { “module/my_plugin@manual": { "class": "Akasima\\Manual", "name": "Manual", "description": "akasima 매뉴얼 모듈", "screenshot" : [ “/plugins/my_plugin/assets/img/screenshots/akasimaManual.jpg" ] } } }},

Page 35: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

35

메뉴 컴포넌트 추가

Page 36: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

36

메뉴를 추가할 수 있습니다.

Page 37: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

37

Routing

라우팅 설정이 없음

Page 38: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

38

Routing 등록

공식사이트, Laravel 문서 참고

Page 39: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

39

Routing 등록http://xpressengine.io/docs/3.0/Routing

Page 40: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

40

class Manual extends AbstractModule{ public static function boot() { Route::instance(self::getId(), function () { Route::get('', ['as' => 'index', 'uses' => 'UserController@index']); Route::get('/edit', ['as' => 'edit', 'uses' => 'UserController@edit']); Route::post('/update', ['as' => 'update', 'uses' => 'UserController@update']); }, ['namespace' => 'Akasima']); }

Routing 등록

Page 41: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

41

namespace Akasima; use App\Http\Controllers\Controller; class UserController extends Controller{ public function index() { return Presenter::make('my_plugin::views.manual.index'); } public function edit() { return 'edit'; } public function update() { return 'update'; } }

Routing 등록UserController.php

Page 42: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

42

<strong>메인페이지 입니다</strong><a href="{{instanceRoute('edit')}}">수정페이지</a>

view bladeviews/manual/index.blade.php

Page 43: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

43

Page 44: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

44

하고 싶은 이야기는 많지만..

12월 12일 오픈 세미나가 있습니다. 더 자세한 얘기는 XEHub 에서

Page 45: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

45

Interception

Page 46: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

46

Interception

Hook Event Trigger

Page 47: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

47

AOP

interception(가로채는) 을 구현하기 위해 AOP 를 도입

Page 48: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

AOP 관점지향 프로그래밍

Aspect Oriented Programming

[Documentation]

Page 49: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

49

Proxy 생성

Service provider 에 정의되어있습니다.

Page 50: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

50

Interception 사용

인터셉션 등록은 plugin boot() 메소드에 정의

intercept( 'Comment@add', 'notification.comment.add', function ($addFunc, CommentEntity $comment, MemberEntityInterface $user = null) { /** * @var $commentNotificator CommentNotificator */ $commentNotificator = app('xe.notification.notificator.comment'); $commentNotificator->notify($comment); $commentEntity = $addFunc($comment, $user); return $commentEntity; } );

Page 51: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

51

Interception 사용댓글 작성시 알림 발송(알림센터)

intercept( 'Comment@add', 'notification.comment.add', function ($addFunc, CommentEntity $comment, MemberEntityInterface $user = null) { /** * @var $commentNotificator CommentNotificator */ $commentNotificator = app('xe.notification.notificator.comment'); $commentNotificator->notify($comment); $commentEntity = $addFunc($comment, $user); return $commentEntity; } );

동작 시점

코드

실제 동작 대상 실행

Page 52: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

52

Interception 사용댓글 작성시 알림 발송 - 댓글

intercept( 'Comment@add', 'notification.comment.add', function ($addFunc, CommentEntity $comment, MemberEntityInterface $user = null) { $commentEntity = $addFunc($comment, $user); /** * @var $commentNotificator CommentNotificator */ $commentNotificator = app('xe.notification.notificator.comment'); $commentNotificator->notify($comment); return $commentEntity; } );

Page 53: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

데이타 베이스 사용하기

53

Page 54: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

데이타 베이스

54

Page 55: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

트랜잭션

55

intercept( 'Comment@add', 'notification.comment.add', function ($addFunc, CommentEntity $comment, MemberEntityInterface $user = null) { XeDB::beginTransaction(); $commentNotificator = app('xe.notification.notificator.comment'); $commentNotificator->notify($comment); $commentEntity = $addFunc($comment, $user); XeDB::commit(); return $commentEntity; } );

Page 56: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

트랜잭션

56

intercept( 'Comment@add', 'notification.comment.add', function ($addFunc, CommentEntity $comment, MemberEntityInterface $user = null) { XeDB::beginTransaction(); $commentNotificator = app('xe.notification.notificator.comment'); $commentNotificator->notify($comment); $commentEntity = $addFunc($comment, $user); XeDB::commit(); return $commentEntity; } );

Page 57: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

데이터 베이스 테이블

57

if (Schema::hasTable(‘table_name') === false) { Schema::create('table_name', function (Blueprint $table) { $table->increments('id'); $table->string('instanceId', 255); $table->string('title', 255); $table->index(array('title')); }); }

Page 58: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

디버깅

58

/storage/log/laravel.log 참고

APP_DEBUG=true

/.env

Page 59: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

캐시 삭제

59

php artisan xeCache:clear

Page 60: XECon2015 :: [3-2] 오승훈 - XE3 플러그인 제작 소개

감사합니다

60