Completed
Push — feature/EVO-3317_logServiceBun... ( f693e5 )
by Bastian
10:42
created

LogExtensionController::postAction()   B

Complexity

Conditions 4
Paths 5

Size

Total Lines 44
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 44
rs 8.5806
cc 4
eloc 22
nc 5
nop 1
1
<?php
2
/**
3
 * dummy "showcase" module
4
 */
5
6
namespace Graviton\LogBundle\Controller;
7
8
use Graviton\RestBundle\Controller\RestController;
9
use Symfony\Component\HttpFoundation\Request;
10
use Symfony\Component\HttpFoundation\Response;
11
12
/**
13
 * This is just a dummy controller for demonstrating
14
 * the extension of generated bundles..
15
 *
16
 * @author   List of contributors <https://github.com/libgraviton/graviton/graphs/contributors>
17
 * @license  http://opensource.org/licenses/gpl-license.php GNU Public License
18
 * @link     http://swisscom.ch
19
 */
20
class LogExtensionController extends RestController
21
{
22
    /**
23
     * Writes a new Entry to the database
24
     *
25
     * @param Request $request Current http request
26
     *
27
     * @return \Symfony\Component\HttpFoundation\Response $response Result of action with data (if successful)
28
     */
29
    public function postAction(Request $request)
30
    {
31
        $response = $this->getResponse();
32
        $response->setStatusCode(Response::HTTP_OK);
33
34
        // get data from request
35
        $content = $request->getContent();
36
37
        if (empty($content)) {
38
            $response->setStatusCode(Response::HTTP_BAD_REQUEST);
39
            $response->setContent('{"error":{"message": "Payload cannot be empty", "code":"400"}}');
40
41
            return $response;
42
        }
43
44
        // is content valid?
45
        $this->formValidator->checkJsonRequest($request, $response, $content);
0 ignored issues
show
Bug introduced by
It seems like $content defined by $request->getContent() on line 35 can also be of type resource; however, Graviton\RestBundle\Vali...orm::checkJsonRequest() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
46
        $decodedContent = json_decode($content, true);
47
48
        // dump to php://stderr
49
        $stderr = fopen('php://stderr', 'w');
50
51
        if (false === $stderr) {
52
            $response->setStatusCode(Response::HTTP_INTERNAL_SERVER_ERROR);
53
            $response->setContent('{"error":{"message": "Could not open error log", "code":"500"}}');
54
55
            return $response;
56
        }
57
58
        try {
59
            // generate log message
60
            $logContent = $this->generateLogMessage($decodedContent);
61
62
            // write to stream
63
            $this->writeToStream($logContent, $stderr);
64
65
        } catch (\RuntimeException $e) {
66
            $response->setStatusCode($e->getCode());
67
            $response->setContent($e->getMessage());
68
69
        }
70
71
        return $response;
72
    }
73
74
    /**
75
     * Returns a single record
76
     *
77
     * @param Request $request Current http request
78
     * @param string  $id      ID of record
79
     *
80
     * @return \Symfony\Component\HttpFoundation\Response $response Response with result or error
81
     */
82
    public function getAction(Request $request, $id)
83
    {
84
        return $this->handleRequest();
85
    }
86
87
    /**
88
     * Returns all records
89
     *
90
     * @param Request $request Current http request
91
     *
92
     * @return \Symfony\Component\HttpFoundation\Response $response Response with result or error
93
     */
94
    public function allAction(Request $request)
95
    {
96
        return $this->handleRequest();
97
    }
98
99
    /**
100
     * Update a record
101
     *
102
     * @param Number  $id      ID of record
103
     * @param Request $request Current http request
104
     *
105
     * @return Response $response Result of action with data (if successful)
106
     */
107
    public function putAction($id, Request $request)
108
    {
109
        return $this->handleRequest();
110
    }
111
112
    /**
113
     * Patch a record
114
     *
115
     * @param Number  $id      ID of record
116
     * @param Request $request Current http request
117
     *
118
     * @return Response $response Result of action with data (if successful)
119
     */
120
    public function patchAction($id, Request $request)
121
    {
122
        return $this->handleRequest();
123
    }
124
125
    /**
126
     * Deletes a record
127
     *
128
     * @param Number $id ID of record
129
     *
130
     * @return Response $response Result of the action
131
     */
132
    public function deleteAction($id)
133
    {
134
        return $this->handleRequest();
135
    }
136
137
    /**
138
     * Generates a http 405 response.
139
     *
140
     * @return Response
141
     */
142
    private function handleRequest()
143
    {
144
        // Get the response object from container
145
        $response = $this->getResponse();
146
147
        $response->setStatusCode(Response::HTTP_METHOD_NOT_ALLOWED);
148
        $response->setContent('[]');
149
150
        return $response;
151
    }
152
153
    /**
154
     * Generates the log message sent to the streamwrapper.
155
     *
156
     * @param string $content Text to be arranged to a log message.
157
     *
158
     * @throws \RuntimeException
159
     * @return string
160
     */
161
    private function generateLogMessage($content)
162
    {
163
        if (empty($content['message'])) {
164
            throw new \RuntimeException(
165
                '{"error":{"message": "There has to be a message to be logged.", "code":"400"}}',
166
                Response::HTTP_BAD_REQUEST
167
            );
168
        }
169
170
        $date = new \DateTime();
171
        $code = 'no code';
172
        $stacktrace = 'no callstack';
173
174
        if (!empty($content['code'])) {
175
            $code = $content['code'];
176
        }
177
        if (!empty($content['callstack'])) {
178
            $stacktrace = implode(", ", $content['callstack']);
179
        }
180
181
        return sprintf(
182
            "%s: %s (%i) - %s",
183
            $date->format('Y-m-d H:i:s'),
184
            $content['message'],
185
            $code,
186
            $stacktrace
187
        );
188
    }
189
190
    /**
191
     * Writes the provided message to the provides streamwrapper.
192
     *
193
     * @param string   $content Text to be sent to the streamwrapper
194
     * @param Resource $stream  Streamwrapper to be used
195
     *
196
     * @throws \RuntimeException
197
     *
198
     * @return void
199
     */
200
    private function writeToStream($content, $stream)
201
    {
202
        $succeed = fwrite($stream, $content);
203
204
        if (false === $succeed || 0 >= $succeed) {
205
            $code = Response::HTTP_INTERNAL_SERVER_ERROR;
206
            $message = '{"error":{"message": "Could not write to error log", "code":"500"}}';
207
208
            throw new \RuntimeException($message, $code);
209
        }
210
    }
211
}
212