개발자 가이드
- XE3 엔진
- 일반적인 가이드
- 언어 작성 표준
- PHP 작성 표준 (psr-2)
- 보완 PHP 작성 표준
- HTML 작성 표준
- Javascript 작성 표준
- CSS 작성 표준
- 데이터베이스 가이드
- 보안 가이드
- 플러그인 로드
- 설치와 삭제
- 번역
- 환경 설정
XE3 엔진
XE를 설치하기 위해서는 아래의 요구사항이 만족되어야 합니다.
- 웹서버(Apache, Nginx 등)
- PHP 7 이상(XE3.0.0-beta.24 부터)
- PDO PHP Extension
- cURL PHP Extension
- FileInfo PHP Extension
- GD PHP Extension
- Mbstring PHP Extension
- OpenSSL PHP Extension
- Zip PHP Extension
- MariaDB or MySQL 5.1 이상
- 터미널 접속 환경
- 디스크 300M 이상의 여유 공간
- 500M 이상 권장
XE3는 아래와 같은 사항들이 지켜져야 합니다.
- Deprecated 된 함수는 사용하지 않습니다
- 관리자 코드는 다른 공개된 코드와 별개로 작성되어야합니다.
auth()→user()→isAdmin()
를 사용해서 관리자인 지 확인할 수 있습니다. - 모든 함수와 클래스, 콜백, 변수, 데이터베이스에는 구분되는 식별자 접두어(prefix)를 붙여 다른 플러그인과 충돌이 일어나지 않도록 방지해야 합니다.
- 필요한 기능들이 이미 XE3에서 제공되는 경우 만들어진 것을 그대로 사용합니다.
- 타사의 API 호출은 적극적으로 캐싱하여 추가적인 호출이 없도록 제한해야 합니다.
- 작성된 플러그인이 이전 버전에 호환되도록 작성된 경우에도 XE3 최신 버전에서 작동하도록 설계해야 합니다. 다른 타사 플러그인이 중요한 업데이트를 수신하도록 설정되어 있을 수 있으므로 사용자가 이전 버전을 계속 사용한다고 볼 수 없습니다.
일반적인 가이드
- 모든 도큐먼트는 온라인 상에서 공개되어 있거나 오프라인상에서 아카이빙 파일을 포함하여 제공되어야 합니다.
- 사용자에게 충분히 고지하지 않고 허가받지 않았다면, 플러그인은 어떤 데이터도 해당 서버를 포함한 어느 제3의 서버에 전송할 수 없습니다.
- 플러그인은 관리자페이지를 통해서 프리미엄 서비스를 상향하거나 광고를 포함해서는 안됩니다. (유로플러그인과 무료플러그인은 별개로 작성되어야 합니다.)
- 사용자 정의 업데이트 로직이 다른 업데이트를 감지 못하게 하거나 알람을 표시하지 않게 하거나 업데이트 처리를 못하도록 방해해서는 안됩니다.
- 사용자에게 플러그인을 활성화하거나 리뷰를 남기도록 요청하는 전역 알림 메시지는 허용되지만 사용자가 해지 할 수 있어야 하며 해지되면 다시 표시 되어선 안됩니다.
- 플러그인은 실행되거나 설치될 때 코어와 플러그인간의 호환성 테스트를 위해 composer.json에 버전을 명시하여야 합니다.
//plugins/plugin_name/composer.json
"require": {
"xpressengine/xpressengine": "~3.0.2"
},
언어작성 표준
PHP 작성 표준 (psr-2)
- PHP 파일
- 모든 PHP 파일은 Unix LF 줄마침을 사용합니다.
- 모든 PHP 파일은 마지막에 공백줄 하나가 삽입되어야 합니다.
- PHP파일이 PHP언어만 가질 경우에 PHP 마감 문법인 '?>'은 사용하지 않습니다.
- 줄(lines)
- 강제적으로 한 줄의 길이를 제한하지는 않습니다.
- 권장하는 가장 보수적인 길이는 120자 입니다. 스타일 체커는 경고는 하지만 에러는띄우지 않을 것 입니다.
- 보통 80자를 넘어가지 않도록 작성합니다. 그 이상을 넘어가면 줄을 바꿔서 작성합니다.
- 비어있지 않는 줄의 마지막에 공백을 넣어선 안됩니다.
- 코드의 가독성을 위해서 구분되는 코드블록 사이에 공백줄을 넣을 수 있습니다.
- 한 줄에 하나 이상의 주석이 있어선 안됩니다.
- 들여쓰기(Indent)
- 코드는 하나의 4번의 띄어쓰기를 사용해 구분합니다. 탭을 사용하지 않습니다.
- PHP 키워드와 true/false/null
- PHP 키워드는 소문자(lower case)로 작성합니다.
- true/false/null도 소문자로 작성합니다.
- 네임스페이스와 선언
- 네임스페이스를 선언한 후에 반드시 공백줄을 하나 아래에 추가합니다.
- use는 반드시 네임스페이스 공백줄 아래부터 작성합니다.
- 선언할 때마다 use 하나를 사용합니다.
- use블록 다음에 반드시 공백줄을 하나 아래에 추가합니다.
- 클래스, 속성, 메소드
- 상속과 구현
- extends와 implements는 반드시 클래스네임과 같은 줄에 작성합니다.
- implements하는 클래스가 많은 경우에는 implements 다음 줄바꿈한 후에 클래스를 한줄에 하나씩 작성합니다.
- 속성
- 범위(public, private, protected)는 반드시 모든 변수에 선언되어야합니다.
- var는 변수명으로 사용할 수 없습니다.
- 한 문장에 하나 이상의 속성이 선언되어선 안됩니다.
- protected나 private 속성을 나타낼 때에 하나의 밑줄(_)을 접두어로 사용할 수 없습니다.
- 메소드
- 범위(public, private, protected)는 반드시 모든 메소드에 선언되어야합니다.
- protected나 private 속성을 나타낼 때에 하나의 밑줄(_)을 접두어로 사용할 수 없습니다.
- 메소드명 이후에 공백을 두어선 안됩니다. 바로 다음 줄에 중괄호로 열고나서 그 다음줄에 코드를 작성하고 작성을 마친후 그 다음 라인에서 중괄호로 닫습니다.
- 여는 중괄호 위나 닫는 중괄호 아래에 공백이 있으면 안됩니다.
- 메소드 전달자(arguments)
- 콤마 이전에 공백을 두지 않고 콤마 이후에 공백을 하나 넣어 작성합니다.
- 기본값을 선언하는 전달자의 경우에는 목록에 가장 나중에 삽입합니다.
- 메소드명과 전달자를 여는 소괄호사이에 공백은 두지 않습니다.
- 한 줄에 넣기 많은 전달자를 사용하는 경우에는 여러 줄에 나누어 삽입할 수 있습니다. 여는 소괄호를 작성하고 줄바꿈을 한 이후에 들여쓰기를 하고 전달자 하나와 콤마 하나를 한 줄에 삽입합니다.
- 여러 줄에 전달자를 나누어 삽입하는 경우에 목록을 닫는 소괄호는 메소드를 시작하는 중괄호와 같은 줄에 배치시킵니다.
- abstract, final, and static
- abstract와 final은 범위(public, private, protected)앞에 선언합니다.
- static은 뒤에 선언합니다.
- 메소드와 함수 호출
- 메소드와 함수를 호출 할 때에는 호출하는 클래스와 메소드명 사이에 공백을 넣지 않습니다.
- 전달자를 시작하는 소괄호에도 공백을 넣지 않습니다.
- 각 전달자 사이의 콤마에만 뒤에 공백을 붙입니다.
- 전달자를 여러 줄에 나누어 작성할 때가 있습니다. 메소드를 작성할 때와 마찬가지로 각 항목과 괄호를 한 줄에 담아 나누어 작성합니다.
- 상속과 구현
- 제어 연산자
- if, elseif, else
- 소괄호 양쪽으로 공백을 작성합니다. 여는 중괄호 이후에 공백없이 줄바꿈을 하고, 닫는 중괄호 이 후에 else가 오는 경우에 여는 중괄호를 같은 줄에 작성합니다.
- switch
- if와 마찬가지로 중괄호를 열고 닫습니다.
- case를 작성할 때에는 줄바꿈후에 들여쓰기를 해야합니다. 이후 코드와 break문은 한번 더 들여씁니다.
- while, do while
- if와 마찬가지로 중괄호를 열고 닫습니다.
- do while 문의 경우에도 do에 괄호가 없을 뿐 while문과 동일하게 작성합니다.
- for
- if문과 마찬가지로 중괄호를 열고 닫습니다.
- 소괄호 내의 세미콜론 앞에는 공백을 삽입하지 않고, 뒤에 삽입합니다.
- 각 비교연산자의 양 옆으로 공백을 삽입합니다.
- foreach
as
와⇒
양 옆에는 공백을 붙입니다.
- try, catch
- if, elseif 문과 크게 다르지 않습니다.
- if, elseif, else
- 클로져
- function 키워드와 use 키워드 양쪽에는 공백을 삽입합니다.
- 되도록 function 과 use를 한 줄에 삽입하며, 다른 함수와 마찬가지로 중괄호까지 연후에 줄바꿈 합니다.
XE용 PHP 작성 표준 개선
PSR-2 권고안을 그대로 사용하되 몇 군데를 완화하거나 수정하여 사용합니다.
- 여백(들여쓰기)은 코드의 논리적인 구조에 맞추어서 일정하게 이루어져야 합니다.
- 탭은 여백의 대안으로 사용할 수 있습니다.
- 테스트할 때에 config/production/app.php 파일에 debug값을 true로 맞추면 디버깅항목이 뷰페이지에 나타납니다.
- 코드는 기본 PHP의 알림이나 경고 에러를 일으켜서는 안됩니다.
- PHP파일은
<?php
로 시작하고 축약형<?
은 사용하지 않습니다. - PHP 파일은 BOM(byte of mask)이 제거된 UTF-8 으로 작성되어야합니다. ( UTF-8 without BOM)
- POSIX Regex 함수(ereg_*)를 사용하는 것은 허용되지 않습니다.
- 모호한 비교연산자인
==
보다는===
와 같은 엄격한 비교연산자를 사용하도록 합니다. - 블록은 항상 중괄호를 사용합니다. 여는 중괄호는 함수 정의, 조건부 또는 루프와 같은 줄에 있어야합니다. 닫는 중괄호는 블록의 마지막 문 바로 다음 줄에 위치해야 합니다.
- eval() 함수는 사용하지 않습니다.
- 규모가 큰 소스는 종속성관리를 하는 것이 좋습니다.
HTML 작성 표준
- 분류되지 않은 태그, 중첩 오류, 중복 된 ID 등은 심각한 에러이지만 브라우저별로 중요하지 않은 에러로 처리하거나 무시될 수 있습니다. 작성자는 W3C 유효성 검사기를 통해 모든 코드를 실행하는 것이 좋습니다.
- HTML도 마찬가지로 논리적인 구조에 맞추어 여백이 이루어져야 합니다.
- 마찬가지로 탭도 여백의 대안으로 사용될 수 있습니다.
Javascript 작성 표준
- JS 코드 스타일은 standardJS를 권장합니다.
- Modern browser에 최적화하고, IE10 및 IE9 또한 고려될 수 있습니다. 오류로 인해 사이트 이용에 영향을 주지 않도록해야 합니다.
- 템플릿에 JS 코드를 작성하지 않고 .js 파일로 분리하여 작성하는 것을 권장합니다.
- 브라우저에 로드하여 사용하는 최종 파일은 minify/uglify를 거친 최적화된 형태를 권장합니다.
- 브라우저에 로드하여 사용하는 최종 파일은 반드시 browserify, babel 등을 이용해 ES5를 지원해야합니다.
- 여러 DOM 변경은 단일 작업으로 적용되거나 전체 DOM 조각을 제거한 후 요소를 업데이트하고 다시 삽입해야 적용되어야 합니다.
- PHP와 마찬가지로 블록은 항상 중괄호를 사용합니다. 여는 중괄호는 함수 정의, 조건부 또는 루프와 같은 줄에 있어야합니다. 닫는 중괄호는 블록의 마지막 문 바로 다음 줄에 위치해야 합니다.
- 정말 필요한 경우가 아니라면 전역 변수/함수는 사용하지 않습니다.
- 전역 변수/함수가 꼭 필요하면
window.varianceName
과 같이 window 객체를 통해 명시적으로 선언하고 사용해야합니다. - 전역 변수/함수가 꼭 필요하면 고유한 접두어를 사용해 분리시켜야 합니다.
- PHP와 마찬가지로 모호한 비교연산자인
==
보다는===
와 같은 엄격한 비교연산자를 사용하도록 합니다. - 다른 함수에서 함수를 중첩 사용해야하는 경우가 있지만 이러한 중첩사용은 종종 성능저하나 좋지 않은 결과를 야기하기도 합니다.
- 이벤트 리스너 및 다량 호출하여 사용하는 동작에서는 결과 값 등을 변수에 저장하여 불필요한 동작을 줄여야 합니다.
- 지역 변수를 재선언하는 것은 권장하지 않습니다.
- 3개 이상에 요소에 동일한 함수를 바인딩한다면 익명 함수보다는 명명된 함수를 사용합니다.
- 코드는 개발자콘솔에서 어떠한 알림이나 에러도 생성해서는 안됩니다.
- 코드는 standardJS 규칙을 통과해야 합니다. standardJS 페이지에서 텍스트 에디터 플러그인 및 툴에 대한 정보를 찾아볼 수 있습니다.
CSS 작성 표준
- 셀렉터에는 반드시 필요한 것을 제외하고는 태그 이름을 사용하지 않습니다.
- id와 class는 목적에 맞도록 적절하게 명명되어야 합니다.
- BEM 이름 규칙 사용을 권장합니다.
- 태그 이름 등을 사용하여 절대 스타일을 제거(CSS Reset 등)하거나 변경하지 않아야 합니다.
- id보다 class 기반 작성을 권장하며, prefix 사용을 권장합니다.
- 지나친 셀렉터 사용은 피하여 가능한 CSS 명시도를 낮춰 최종사용자가 이를 쉽게 변경, 확장할 수 있도록해야 합니다.
- CSS 명시도 - MDN
- CSS 적용 우선순위 - Opentutorials
- http://cssspecificity.com
- SASS 등을 사용할 수 있으며, 최종 파일은 CSS 포맷으로 생성해야 합니다.
- 마크업에 직접적으로 inline CSS를 사용하는 것은 지양합니다.
- 2개의 공백으로 들여쓰기 합니다.
- 중괄호는 셀렉터와 같은 줄에서 열고, 마지막 속성 정의에서 줄을 바꿔 닫아야 합니다.
- 셀렉터와 속성 정의는 줄을 바꿔 구분해야합니다.
- 모든 속성 정의는 반드시 세미콜론으로 닫아야 합니다. 마지막 항목에 세미콜론을 생략하지 마세요.
- 섹션을 열고 닫을 때에 사용되는 주석은 유용하고 사용목적을 나타내기 때문에 권장합니다.
!important
는 절대 사용하지 않습니다.- 요소를 다룰때에는 반드시 의도한 요소들만 다뤄지도록 주의해야합니다. 익스텐션, 테마의 이름 등을 활용해 상위 요소에 class를 추가하거나 prefix를 사용하세요.
데이터베이스 가이드
- 직접적으로 db에 접근하는 것을 금합니다. 대신에 laravel과 xe에서 제공하는 쿼리빌더를 사용해주세요.
- 플러그인은 최소한의 갯수로 테이블을 생성해야하고, 가능한 변경과 조작이 가능한 게시 유형 및 분류를 사용해야합니다.
- 모든 쿼리는 sql인젝션에서 보호받아야 하며,
DB::beginTransaction()
,DB::commit()
과 같은 함수를 통해 관리할 수 있습니다. - 정적인 데이터에 굉장히 많은 쿼리가 들어가야하는 경우 가능하면 캐싱하세요.
- *를 통해 모든 정보를 불러오기보다는 필요한 항목만 로드하도록 합니다.
- 테이블을 생성할 때에는 목적에 따라 일반적으로 검증된 테이블설계를 사용합니다.
보안 가이드
- 모든 것을 검증하고 필터링하고 이스케이프 합니다.
- 사용자가 입력한 값이 어플리케이션에 입력되기전에 되도록 충분한 검증과 필터링을 거쳐야 합니다.
- 사용자 입력을 필터링 할때에는 되도록 화이트리스트 (정해진 포맷 이외는 받아들이지 않음. 반대는 블랙리스트: 정해진포맷외의 모든 것을 받아들임) 방식을 사용하도록 합니다.
- post방식의 폼을 받을 때에는 csrf 취약점 공격을 방지하기위해
csrf_field()
또는csrf_token()
값을 사용하여 함께 전달합니다. - 모든 쿼리는 쿼리빌더를 사용하여 sql 인젝션에서 보호받을 수 있도록합니다.
- 관리자페이지는 항상 주의를 기울여 권한이 없는 사용자의 접근에서 보호받도록 조치해주십시오.
플러그인 로드
- XE3 코어에서 사용하고 있는 jQuery 버전은 등록해제하지 않습니다.
- javascript와 css는 직접적으로 호출하지 않습니다.
- 이미 XE3 코어에서 등록되어있는 라이브러리를 다른 버전이나 같은 버전의 라이브러리로 교체하여 사용하지 않습니다.
설치와 삭제
- 플러그인은 비활성화 되어있는 상태에서는 사용하던 데이터를 삭제하지 않아야합니다.
- 플러그인은 삭제가 되는 시점에서 사용자에게 데이터에 삭제에 대한 안내문구를 띄우고 확인을 받는 절차를 통해 데이터를 삭제하거나 또는 데이터를 지우지않고 보호할 수 있어야 합니다.
- 데이터를 삭제하기전에 데이터를 import하거나 export할 수 있는 옵션을 제공하여, XE3 외부에 설정을 저장할 수 있도록 합니다.
번역
다음과 같은 다국어 규칙을 적용합니다.
- 번역가능한 문장 : 모든 텍스트들은 다국어적용이 가능해야하고 적절하게 이스케이프되어 사용자가 테마와 같은 옵션 수정을 하지 않더라도 번역된 내용을 확인할 수 있어야합니다.
- 번역가능한 변수 : 동적인 내용들은 번역할 수 없으므로 텍스트 문자열에는 상수나 변수가 그대로 들어가서는 안됩니다.
__()
함수나xe_trans
함수를 통해서 미리 정의해둔 언어로케일에 따라서 해당 문자열을 반환할 수 있도록 해주십시오. - 도메인 정의 : 상수, 변수 또는 정의를 사용하여 테마의 텍스트 도메인을 정의해서는 안됩니다. 텍스트 도메인은 밑줄(_)이 아닌 대시(-)를 사용해야하며 소문자 일반 텍스트 여야합니다.
- 불필요한 도메인 정의 : 테마와 관련없는 텍스트 도메인은 허용되지 않으므로 제거해야합니다.
- 다국어 에셋 : 코어에서 제공하는 다국어파일은 resoures/lang 폴더에, 나머지 플러그인에서 등록하는 언어들은 database에 translation테이블에 등록됩니다.
XeLang::save()
함수를 사용해서 각 언어에 맞는 언어를 등록할 수 있습니다.