1: <?php
2: /**
3: * Slim - a micro PHP 5 framework
4: *
5: * @author Josh Lockhart <info@slimframework.com>
6: * @copyright 2011 Josh Lockhart
7: * @link http://www.slimframework.com
8: * @license http://www.slimframework.com/license
9: * @version 2.2.0
10: * @package Slim
11: *
12: * MIT LICENSE
13: *
14: * Permission is hereby granted, free of charge, to any person obtaining
15: * a copy of this software and associated documentation files (the
16: * "Software"), to deal in the Software without restriction, including
17: * without limitation the rights to use, copy, modify, merge, publish,
18: * distribute, sublicense, and/or sell copies of the Software, and to
19: * permit persons to whom the Software is furnished to do so, subject to
20: * the following conditions:
21: *
22: * The above copyright notice and this permission notice shall be
23: * included in all copies or substantial portions of the Software.
24: *
25: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26: * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27: * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28: * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29: * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30: * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31: * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32: */
33: namespace Slim\Middleware;
34:
35: /**
36: * Content Types
37: *
38: * This is middleware for a Slim application that intercepts
39: * the HTTP request body and parses it into the appropriate
40: * PHP data structure if possible; else it returns the HTTP
41: * request body unchanged. This is particularly useful
42: * for preparing the HTTP request body for an XML or JSON API.
43: *
44: * @package Slim
45: * @author Josh Lockhart
46: * @since 1.6.0
47: */
48: class ContentTypes extends \Slim\Middleware
49: {
50: /**
51: * @var array
52: */
53: protected $contentTypes;
54:
55: /**
56: * Constructor
57: * @param array $settings
58: */
59: public function __construct($settings = array())
60: {
61: $this->contentTypes = array_merge(array(
62: 'application/json' => array($this, 'parseJson'),
63: 'application/xml' => array($this, 'parseXml'),
64: 'text/xml' => array($this, 'parseXml'),
65: 'text/csv' => array($this, 'parseCsv')
66: ), $settings);
67: }
68:
69: /**
70: * Call
71: */
72: public function call()
73: {
74: $mediaType = $this->app->request()->getMediaType();
75: if ($mediaType) {
76: $env = $this->app->environment();
77: $env['slim.input_original'] = $env['slim.input'];
78: $env['slim.input'] = $this->parse($env['slim.input'], $mediaType);
79: }
80: $this->next->call();
81: }
82:
83: /**
84: * Parse input
85: *
86: * This method will attempt to parse the request body
87: * based on its content type if available.
88: *
89: * @param string $input
90: * @param string $contentType
91: * @return mixed
92: */
93: protected function parse ($input, $contentType)
94: {
95: if (isset($this->contentTypes[$contentType]) && is_callable($this->contentTypes[$contentType])) {
96: $result = call_user_func($this->contentTypes[$contentType], $input);
97: if ($result) {
98: return $result;
99: }
100: }
101:
102: return $input;
103: }
104:
105: /**
106: * Parse JSON
107: *
108: * This method converts the raw JSON input
109: * into an associative array.
110: *
111: * @param string $input
112: * @return array|string
113: */
114: protected function parseJson($input)
115: {
116: if (function_exists('json_decode')) {
117: $result = json_decode($input, true);
118: if ($result) {
119: return $result;
120: }
121: }
122: }
123:
124: /**
125: * Parse XML
126: *
127: * This method creates a SimpleXMLElement
128: * based upon the XML input. If the SimpleXML
129: * extension is not available, the raw input
130: * will be returned unchanged.
131: *
132: * @param string $input
133: * @return \SimpleXMLElement|string
134: */
135: protected function parseXml($input)
136: {
137: if (class_exists('SimpleXMLElement')) {
138: try {
139: return new \SimpleXMLElement($input);
140: } catch (\Exception $e) {
141: // Do nothing
142: }
143: }
144:
145: return $input;
146: }
147:
148: /**
149: * Parse CSV
150: *
151: * This method parses CSV content into a numeric array
152: * containing an array of data for each CSV line.
153: *
154: * @param string $input
155: * @return array
156: */
157: protected function parseCsv($input)
158: {
159: $temp = fopen('php://memory', 'rw');
160: fwrite($temp, $input);
161: fseek($temp, 0);
162: $res = array();
163: while (($data = fgetcsv($temp)) !== false) {
164: $res[] = $data;
165: }
166: fclose($temp);
167:
168: return $res;
169: }
170: }
171: