# Controller 소개

{% hint style="info" %}
`Controller`는 Framework의 구동을 제외한 \
솔루션의 기본 공통 작업부터 화면 출력까지의 업무를 담당합니다.
{% endhint %}

## 📌 Controller 실행 순서 <a href="#controller" id="controller"></a>

1. `view (템플릿 엔진)` 설정
2. `Setup()`
   * 해당 화면에서 사용될 interceptor 설정 (인증, 레이아웃 설정, 공통변수 설정 등)
   * 사용자 정의 데이터 설정 (추후 지원)
3. `pre()` 실행 (사용자 정의 전처리)
4. interceptor 실행 (시스템 전처리)
   * 설정된 `interceptor` 의 `preHandle` 메소드 실행
   * 환경설정에 등록된 순서에 따라서 순차적으로 `interceptor` 실행
5. `index()`
   * 해당 Controller에서 실행되는 구문 (사용자 정의 가능 영역)
6. interceptor 실행 (시스템 후처리)
   * 설정된 `interceptor` 의 `postHandle` 메소드 실행
   * 실행 순서는 `interceptor` 등록 역순
7. `post()` 실행 (사용자 정의 후처리)
8. `fetch()`
   * 구성된 view를 html로 수신
9. `render()`
   * `header`를 설정한 후 수신된 html 데이터를 화면에 출력

## 📌 Controller 상속 구조 <a href="#controller" id="controller"></a>

![](http://localhost:63343/markdownPreview/1494396028/fileSchemeResource/e54cbd0178fd58e50c34316e5dd4a489-Controller5.png?_ijt=r8qjcqaepapne9qdf7cmkjqnbl)

* `AbstractController`는 추상화를 목적으로 `index()`, `setup()`, `pre()`, `post()`의 추상 메서드가 설정되어 있으며 최종적으로 화면 출력을 담당합니다.
* `ActionController`는 컨트롤러가 할 수 있는 `action`에 대해 정의되어 있습니다.
* `Controller`는 위젯, 플러스샵, 헤더설정 및 `Controller`에서 사용하는 절대상수를 정의합니다.
* `Widget`은 넓게 보면 컨트롤러 개념이지만 현 컨트롤러에 종속되어 부분적으로 프로그램+템플릿을 표현할 수 있습니다.

## 📌 Controller Implement <a href="#controller-implement" id="controller-implement"></a>

### 사용자(PC) 영역

```php
<?php
namespace Bundle\Controller\Front\Test;

class MyController extends \Controller\Front\Controller {
    public function index() {
        something();
    }
}
```

### 사용자(Mobile) 영역

```php
<?php
namespace Bundle\Controller\Mobile\Test;

class MyController extends \Controller\Mobile\Controller {
    public function index() {
        something();
    }
}
```

### 관리자 영역

```php
<?php
namespace Bundle\Controller\Admin\Test;

class MyController extends \Controller\Admin\Controller {
    public function index() {
        something();
    }
}
```

### 위젯 영역

```php
<?php
namespace Bundle\Widget\Front\Test;

class MyWidget extends \Widget\Front\Widget {
    public function index() {
        something();
    }
}
```

### API 영역

```php
<?php
namespace Bundle\Controller\Api\Test;

class MyController extends \Controller\Api\Controller {
    public function index() {
        something();
    }
}
```

## 📌 Controller Extends <a href="#controller-extends" id="controller-extends"></a>

### **User Source Directory**

* `module/Controller/Front/Test/MyController.php`

  ```php
  <?php

  namespace Bundle\Controller\Front\Test;

  class MyController extends \Controller\Front\Test\Controller {
      protected function func() {
          return '456';
      }
  }
  ```
* result

  ```
  [ 'test' => '456' ]
  ```

### **API**

* `module/Controller/api/Test/MyController.php`

  ```php
  <?php

  namespace Bundle\Controller\Api\Test;

  class MyController extends \Controller\Api\Test\Controller {
      protected function func() {
          // some code ...
      }
  }
  ```

## 📌 Data Handling <a href="#data-handling" id="data-handling"></a>

{% hint style="info" %}
`Controller` 의 `index()` 실행 후 `interceptor` 후처리를 통해 `DataHandler interceptor`가 실행 되면서 uri에 대응하는 위치에 있는 파일이 실행됩니다. 파일 안에서는 `$data` 변수를 통해 `data`를 가공할 수 있습니다.
{% endhint %}

ex) `사용자 소스 디렉토리(User Source Directory)` 내 `goods/goods_list.php`에 파일을 생성하고 다음과 같이 작성합니다.

* `Bundle/Controller/Front/Goods/GoodsListController.php`

  ```php
  <?php
  namespace Bundle\Controller\Front\Goods;

  class GoodsListController extends \Controller\Front\Controller {
      public function index() {
          $this->setData('data', 'original');
      }
  }
  ```
* `goods/goods_list.php`

  ```php
  <?php

  $data['data'] = 'not original';
  $data['data2'] = 'new data';
  ```
* result \[ 'data' => 'not original', 'data2' => 'new data' ]

## 📌 View Rendering <a href="#view-rendering" id="view-rendering"></a>

### View 출력 예제

```php
<?php
namespace Bundle\Controller\[Front|Admin|Mobile]\Test;

class MyController extends \Controller\[Front|Admin|Mobile]\Controller {
    public function index() {
        // somecode or data handling				
    }
}
```

### JSON 출력 예제

```php
<?php
namespace Bundle\Controller\[Front|Admin|Mobile]\Test;

class MyController extends \Controller\[Front|Admin|Mobile]\Controller {
    public function index() {
        // case 1
        $this->setData('wrapper', [
            'test1' => 1,
            'test2' => 2,
            'test3' => 3,
        ]);
        $this->json();
        
        // case 2
        $data = [
            'wrapper' => [
                'test1' => 1,
                'test2' => 2,
                'test3' => 3,
            ]
        ]);
        $this->json($data);
    }
}
```

### 파일 다운로드 예제

```php
<?php
namespace Bundle\Controller\[Front|Admin|Mobile]\Test;

class MyController extends \Controller\[Front|Admin|Mobile]\Controller {
    public function index() {
        // 파일경로와 파일명을 인자로 넘기면 즉시 다운로드가 실행됩니다
        $this->download(UserFilePath::frontSkin('mera_ws','img','btn_19out.gif'), 'sample_test.gif');
    }
}
```

### 스트림 파일 다운로드 예제

```php
<?php
namespace Bundle\Controller\[Front|Admin|Mobile]\Test;

class MyController extends \Controller\[Front|Admin|Mobile]\Controller {
    /**
     * index() 함수내 echo를 이용해 화면에 출력하면
     * 출력 버퍼를 이용해 파일로 저장합니다.
     */
    public function index() {
        // case 1
        echo '인덱스내에 스트링을 출력하면 해당 내용이 결과로 저장되며, 파일 확장자에 따라서 자동으로 Mime-Type이 설정됩니다.';
        $this->streamedDownload('sample_test.txt');
        
        // case 2
        echo '<table><tr><td>엑셀</td></tr></table>';
        $this->streamedDownload('sample_test.xls');
    }
}
```

### 리다이렉트 예제

```php
<?php
namespace Bundle\Controller\[Front|Admin|Mobile]\Test;

class MyController extends \Controller\[Front|Admin|Mobile]\Controller {
    public function index() {
        $this->redirect('../order/cart');
    }
}
```
