# Responses

All controllers must return a response to be sent back to the user's browser. Siteadmin provides many response types which configure the appropriate headers for each content type.

### HTML Response

```php
<?php
use sa\application\controller;
use sa\application\responses\View;
​
class UserController extends controller {
    public function index() {
        // Use master theme.
        // Render the '/{module}/views/user_list.php' view
        $html = new View('master', 'user_list');
        
        // Pass variables $first_name and $last_name into HTML view.
        $html->data = array('first_name' => 'John', 'last_name' => 'Doe');
        
        // Render the view
        return $html;
    }
}
```

#### Constructor Parameters

| Field         | Type   | Optional/Required | Definition                                                                                                                                                  |
| ------------- | ------ | ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| $template     | string | required          | The layout to wrap around the HTML content. Use `null` for no layout. Use `master` for default application layout.                                          |
| $view         | string | required          | The HTML content to render in the template. Siteadmin will search for the template in `/themes/{theme}/views`, then `/modules/{module}/views` if not found. |
| $location     | string | optional          | Location of the view. To load a view from a different module, use `\{vendor}\{module}\SomeController::viewLocation()`.                                      |
| $responseCode | int    | optional          | HTTP response code (200, 404, etc.)                                                                                                                         |

### JSON Response

```php
<?php
use sa\application\controller;
use sa\application\responses\Json;
​
class UserController extends controller {
    public function index() {
        $json = new Json();
        
        // Set json content.
        $json->data = array('first_name' => 'John', 'last_name' => 'Doe');
        
        // render json
        return $json;
    }
}
```

#### Constructor Parameters

| Field         | Type | Optional/Required | Definition                          |
| ------------- | ---- | ----------------- | ----------------------------------- |
| $responseCode | int  | optional          | HTTP response code (200, 404, etc.) |

### XML Response

```php
<?php
use sa\application\controller;
use sa\application\responses\Xml;
​
class UserController extends controller {
    public function index() {
        $xml = new Xml('root_tag', 'namespace', 200);
        
        // Set XML content.
        $xml->data = array('first_name' => 'John', 'last_name' => 'Doe');
        
        // render xml
        return $xml;
    }
}
```

#### Constructor Parameters

| Field         | Type   | Optional/Required | Definition                          |
| ------------- | ------ | ----------------- | ----------------------------------- |
| $rootTag      | string | required          | The XML document's root tag.        |
| $namespace    | string | optional          | XML namespace definition.           |
| $responseCode | int    | optional          | HTTP response code (200, 404, etc.) |

### File/Binary Response

Renders a file, such as an image or PDF, in the browser.

```php
<?php
use sa\application\controller;
use sa\application\responses\File;
​
class UserController extends controller {
    public function index() {
        $file = new File('/path/to/file.ext');
        
        // render or download file
        return $file;
    }
}
```

#### Constructor Parameters

| Field     | Type   | Optional/Required | Definition    |
| --------- | ------ | ----------------- | ------------- |
| $filePath | string | required          | Path to file. |

### HTTP Redirect

```php
<?php
use sa\application\controller;
use sa\application\responses\Redirect;
​
class UserController extends controller {
    public function index() {
        // 302 temporary redirect
        $redirect = new Redirect('/url-to-new-page');
        
        // 301 permanent redirect
        $redirect = new Redirect('/url-to-new-page', true);
        
        return $redirect;
    }
}
```

#### Constructor Parameters

| Field        | Type    | Optional/Required | Definition                                                                     |
| ------------ | ------- | ----------------- | ------------------------------------------------------------------------------ |
| $location    | string  | required          | A website URL. (e.g. <http://domain.com> or /path/on/current/website)          |
| $isPermanent | boolean | false             | Default: false. If true, 301 redirect header will be included in the response. |

## Custom Responses

### The Response Interface

All responses must implement the `sa\application\responses\ISaResponse` interface. This requires your custom response to include the following methods,

| Method        | Returns | Description                                                                                |
| ------------- | ------- | ------------------------------------------------------------------------------------------ |
| buildResponse | void    | Sets appropriate headers for the response.                                                 |
| getResponse   | string  | Serializes the response's data into a string.                                              |
| getHeaders    | array   | Returns key-value pairs as an array, where the key is a header and the value is its value. |

### The Response Trait

Most responses allow the developer to set custom headers and a custom response code. A wrapper for this exists through the `\sa\application\responses\TViews` trait, which exposes a `headers` property, as well as a helper method for setting the response code: `setResponseCode()`.

| Method/Property            | Type     | Description                                                                                   |
| -------------------------- | -------- | --------------------------------------------------------------------------------------------- |
| headers                    | array    | An associative array of headers. The key is the header name. The value is the header content. |
| setResponseCode($httpCode) | function | Sets the response code for the request to the given HTTP code.                                |

### Custom Response Example

```php
<?php
use sa\application\responses\ISaResponse;
use sa\application\responses\TViews;
use sa\application\responses\ResponseHeader;

class Yaml implements ISaResponse {
    use TViews;
    
    public $data = array();
    private $responseCode;

    public function __construct($responseCode = 200) {
        $this->responseCode = $responseCode;
    }

    /**
     * Gets called before getHeaders and getResponse
     */
    public function buildResponse()
    {
        $this->setResponseCode($this->responseCode);
        $this->headers[] = new ResponseHeader('Content-Type', 'application/x-yaml');
    }

    /**
     * Gets the response content to be echo to the user
     *
     * @return string
     */
    public function getResponse()
    {
        return yaml_emit($this->data);
    }

    /**
     * Gets the headers to be sent to the user
     *
     * @return array();
     */
    public function getHeaders()
    {
        return $this->headers;
    }
}
```

## Downloading Files

Sometimes an application will need to download a file instead of rendering its contents in the browser. This is useful for exporting XML, images, word documents, zip files, among others.

### The Downloadable Response Trait

Download capabilities are exposed through the `DownloadableResponseTrait` . This trait exposes a `setDownloadable()` method which accepts a file name as its only parameter. Once this method is executed, the response object will configure the necessary headers to download its contents as a file.

The following response types implement this trait:

* JSON
* XML
* File

### Download JSON

```php
public function downloadJson() {
    $json = new Json();
    $json->data = [
        "id" => 1,
        "first_name" => "John",
        "last_name" => "Doe"
    ];

    $json->setDownloadable('member.json');
    return $json;
}

public function downloadXml() {
    $member = modRequest::request('auth.member');
    $xml = new Xml('member');
    $xml->data = doctrineUtils::getEntityArray($member);

    $xml->setDownloadable('test.xml');
    return $xml;
}
```

### Download XML

```php
public function downloadXml() {
    $xml = new Xml('member');
    $xml->data = [
        "id" => 1,
        "first_name" => "John",
        "last_name" => "Doe"
    ];

    $xml->setDownloadable('member.xml');
    return $xml;
}
```

### Download Files

The `File` response can be used to download any type of file. Common use cases include:

* CSV
* Images
* PDFs
* Word Documents

...or any other type of file.

```php
public function downloadFile() {
    // Download file from the module's /img directory.
    $file = new File(__DIR__ . '/../img/photo_1.png');
    $file->setDownloadable('photo_1.png');
    return $file;
}
```
