AbstractAccept::considerProvisions()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 1
1
<?php
2
/*
3
 * This file is part of the Respect\Rest package.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 */
8
9
namespace Respect\Rest\Routines;
10
11
use SplObjectStorage;
12
use Respect\Rest\Request;
13
14
/** Base class for content-negotiation */
15
abstract class AbstractAccept extends AbstractCallbackMediator implements
16
    ProxyableBy,
17
    ProxyableThrough,
18
    Unique,
19
    IgnorableFileExtension
20
{
21
    protected $negotiated = null;
22
    protected $request_uri;
23
24 27
    protected function identifyRequested(Request $request, $params)
0 ignored issues
show
Coding Style introduced by
identifyRequested uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

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

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
25
    {
26 27
        $this->request_uri = $request->uri;
27
28 27
        if (!isset($_SERVER[static::ACCEPT_HEADER])) {
29
            return array();
30
        }
31 27
        $acceptHeader = $_SERVER[static::ACCEPT_HEADER];
32 27
        $acceptParts = explode(',', $acceptHeader);
33 27
        $acceptList = array();
34 27
        foreach ($acceptParts as $k => &$acceptPart) {
35 27
            $parts = explode(';q=', trim($acceptPart));
36 27
            $provided = array_shift($parts);
37 27
            $quality = array_shift($parts) ?: (10000 - $k) / 10000;
38 27
            $acceptList[$provided] = $quality;
39
        }
40 27
        arsort($acceptList);
41
42 27
        return array_keys($acceptList);
43
    }
44 27
    protected function considerProvisions($requested)
45
    {
46 27
        return $this->getKeys(); // no need to split see authorize
47
    }
48 26
    protected function notifyApproved($requested, $provided, Request $request, $params)
0 ignored issues
show
Coding Style introduced by
notifyApproved uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

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

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
49
    {
50 26
        $this->negotiated = new SplObjectStorage();
51 26
        $this->negotiated[$request] = $this->getCallback($provided);
52 26
        if (false === strpos($provided, '.')) {
53 21
            $header_type = preg_replace(
54
                array(
55 21
                    '/(^.*)(?=\w*$)/U', // select namespace to strip
56
                    '/(?!^)([A-Z]+)/',   // select camels to add -
57
                ),
58 21
                array('', '-$1'),
59 21
                get_class($this)
60
            );
61
62 21
            $content_header = 'Content-Type';
63
64 21
            if (false !== strpos($header_type, '-')) {
65 12
                $content_header = str_replace('Accept', 'Content', $header_type);
66
            }
67
68 21
            header("$content_header: $provided");                   // RFC 2616
69 21
            header("Vary: negotiate,".strtolower($header_type));    // RFC 2616/2295
70 21
            header("Content-Location: {$_SERVER['REQUEST_URI']}");  // RFC 2616
71 21
            header('Expires: Thu, 01 Jan 1980 00:00:00 GMT');       // RFC 2295
72 21
            header('Cache-Control: max-age=86400');                 // RFC 2295
73
        }
74 26
    }
75 1
    protected function notifyDeclined($requested, $provided, Request $request, $params)
76
    {
77 1
        $this->negotiated = false;
78 1
        header('HTTP/1.1 406');
79 1
    }
80
81 10
    protected function authorize($requested, $provided)
82
    {
83
        // negotiate on file extension
84 10
        if (false !== strpos($provided, '.')) {
85 5
            if (false !== stripos($this->request_uri, $provided)) {
86 5
                return true;
87
            }
88
        }
89
90
        // normal matching requirements
91 5
        return $requested == $provided;
92
    }
93
94 23
    public function by(Request $request, $params)
95
    {
96 23
        $unsyncedParams = $request->params;
97 23
        $extensions = $this->filterKeysContain('.');
98
99 23
        if (empty($extensions) || empty($unsyncedParams)) {
100 22
            return;
101
        }
102
103 1
        $unsyncedParams[] = str_replace(
104 1
            $extensions,
105 1
            '',
106 1
            array_pop($unsyncedParams)
107
        );
108 1
        $request->params = $unsyncedParams;
109 1
    }
110
111 23
    public function through(Request $request, $params)
112
    {
113 23
        if (!isset($this->negotiated[$request])
114 23
            || false === $this->negotiated[$request]) {
115
            return;
116
        }
117
118 23
        return $this->negotiated[$request];
119
    }
120
}
121