Completed
Push — master ( 453641...f48fae )
by Bernhard
02:10
created

src/DiscoveryUrlGenerator.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
/*
4
 * This file is part of the puli/url-generator package.
5
 *
6
 * (c) Bernhard Schussek <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Puli\UrlGenerator;
13
14
use Puli\Discovery\Api\Discovery;
15
use Puli\Discovery\Binding\ResourceBinding;
16
use Puli\UrlGenerator\Api\CannotGenerateUrlException;
17
use Puli\UrlGenerator\Api\UrlGenerator;
18
use Webmozart\Glob\Glob;
19
20
/**
21
 * A resource URL generator that uses a {@link ResourceDiscovery} as backend.
22
 *
23
 * @since  1.0
24
 *
25
 * @author Bernhard Schussek <[email protected]>
26
 */
27
class DiscoveryUrlGenerator implements UrlGenerator
28
{
29
    /**
30
     * The binding type of public resources.
31
     */
32
    const BINDING_TYPE = 'puli/public-resource';
33
34
    /**
35
     * The binding parameter used for the server name.
36
     */
37
    const SERVER_PARAMETER = 'server';
38
39
    /**
40
     * The binding parameter used for the public path.
41
     */
42
    const PATH_PARAMETER = 'path';
43
44
    /**
45
     * @var Discovery
46
     */
47
    private $discovery;
48
49
    /**
50
     * @var string[]
51
     */
52
    private $urlFormats;
53
54
    /**
55
     * Creates the URL generator.
56
     *
57
     * @param Discovery $discovery  The resource discovery.
58
     * @param string[]  $urlFormats The URL formats indexed by the server names.
59
     */
60 8
    public function __construct(Discovery $discovery, array $urlFormats)
61
    {
62 8
        $this->discovery = $discovery;
63 8
        $this->urlFormats = $urlFormats;
64 8
    }
65
66
    /**
67
     * {@inheritdoc}
68
     */
69 8
    public function generateUrl($repositoryPath, $currentUrl = null)
70
    {
71 8
        $matchedBinding = null;
72 8
        $bindings = $this->discovery->findBindings(self::BINDING_TYPE);
73
74 8
        foreach ($bindings as $binding) {
75
            /** @var ResourceBinding $binding */
76 7
            if (Glob::match($repositoryPath, $binding->getQuery())) {
77 7
                $matchedBinding = $binding;
78 7
                break;
79
            }
80 8
        }
81
82 8
        if (null === $matchedBinding) {
83 1
            throw new CannotGenerateUrlException(sprintf(
84 1
                'Cannot generate URL for "%s". The path is not public.',
85
                $repositoryPath
86 1
            ));
87
        }
88
89
        // We can't prevent a resource to be mapped to more than one public path
90
        // For now, we'll just take the first one and make the user responsible
91
        // for preventing duplicates
92 7
        $url = $this->generateUrlForBinding($matchedBinding, $repositoryPath);
93
94 6
        if ($currentUrl) {
0 ignored issues
show
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
95
            // TODO use Url::makeRelative() once it exists
96
        }
97
98 6
        return $url;
99
    }
100
101 7
    private function generateUrlForBinding(ResourceBinding $binding, $repositoryPath)
102
    {
103 7
        $serverName = $binding->getParameterValue(self::SERVER_PARAMETER);
104
105 7
        if (!isset($this->urlFormats[$serverName])) {
106 1
            throw new CannotGenerateUrlException(sprintf(
107 1
                'The server "%s" mapped for path "%s" does not exist.',
108 1
                $serverName,
109
                $repositoryPath
110 1
            ));
111
        }
112
113 6
        $repoBasePath = Glob::getStaticPrefix($binding->getQuery());
114 6
        $serverBasePath = trim($binding->getParameterValue(self::PATH_PARAMETER), '/');
115
116
        // The server path is generated by replacing the base repository path
117
        // (= the path of the binding) by the stored server base path in the
118
        // repository path of the resource.
119
        //
120
        // Example:
121
        //
122
        // resource path: /acme/blog/public/css/style.css
123
        // binding path: /acme/blog/public{,/**/*}
124
        // repo base path: /acme/blog/public
125
        // server base path: /blog
126
        //
127
        // final server path: /blog/css/style.css
128
129 6
        $serverPath = substr_replace($repositoryPath, $serverBasePath, 0, strlen($repoBasePath));
130
131
        // The server path is inserted into the "%s" parameter of the URL format
132 6
        return sprintf($this->urlFormats[$serverName], ltrim($serverPath, '/'));
133
    }
134
}
135