Completed
Push — master ( 4ab803...4a4860 )
by Vladimir
02:28
created

PermalinkDocument::handleSpecialRedirects()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 1
nc 1
nop 0
crap 1
1
<?php
2
3
/**
4
 * @copyright 2017 Vladimir Jimenez
5
 * @license   https://github.com/allejo/stakx/blob/master/LICENSE.md MIT
6
 */
7
8
namespace allejo\stakx\Document;
9
10
use allejo\stakx\Service;
11
use allejo\stakx\System\ReadableFile;
12
13
/**
14
 * A document that will have a permalink
15
 */
16
abstract class PermalinkDocument extends ReadableFile
17
{
18
    /** @var array */
19
    protected $permalink;
20
21
    /** @var array */
22
    protected $redirects;
23
24
    /**
25
     * Get the destination of where this Content Item would be written to when the website is compiled.
26
     *
27
     * @return string
28
     */
29 20
    final public function getTargetFile()
30
    {
31 20
        $permalink = $this->getPermalink();
32 20
        $missingFile = (substr($permalink, -1) == '/');
33 20
        $permalink = str_replace('/', DIRECTORY_SEPARATOR, $permalink);
34
35 20
        if ($missingFile)
36
        {
37 12
            $permalink = rtrim($permalink, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . 'index.html';
38
        }
39
40 20
        return ltrim($permalink, DIRECTORY_SEPARATOR);
41
    }
42
43
    /**
44
     * Get the permalink of this Content Item.
45
     *
46
     * @throws \Exception
47
     *
48
     * @return string
49
     */
50 39
    final public function getPermalink()
51
    {
52 39
        $this->buildPermalink();
53
54 39
        $this->permalink = $this->sanitizePermalink($this->permalink);
0 ignored issues
show
Documentation introduced by
$this->permalink is of type array, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Documentation Bug introduced by
It seems like $this->sanitizePermalink($this->permalink) of type string is incompatible with the declared type array of property $permalink.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
55 39
        $this->permalink = str_replace(DIRECTORY_SEPARATOR, '/', $this->permalink);
0 ignored issues
show
Documentation Bug introduced by
It seems like str_replace(DIRECTORY_SE... '/', $this->permalink) of type string is incompatible with the declared type array of property $permalink.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
56 39
        $this->permalink = '/' . ltrim($this->permalink, '/'); // Permalinks should always use '/' and not be OS specific
0 ignored issues
show
Documentation Bug introduced by
It seems like '/' . ltrim($this->permalink, '/') of type string is incompatible with the declared type array of property $permalink.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
57
58 39
        return $this->permalink;
59
    }
60
61
    /**
62
     * Get an array of URLs that will redirect to.
63
     *
64
     * @return string[]
0 ignored issues
show
Documentation introduced by
Should the return type not be null|array?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
65
     */
66 14
    final public function getRedirects()
67
    {
68 14
        if (is_null($this->redirects))
69
        {
70 3
            $this->getPermalink();
71
        }
72
73 14
        $this->handleSpecialRedirects();
74
75 14
        return $this->redirects;
76
    }
77
78
    /**
79
     * Get the permalink based off the location of where the file is relative to the website. This permalink is to be
80
     * used as a fallback in the case that a permalink is not explicitly specified in the Front Matter.
81
     *
82
     * @return string
83
     */
84 3
    protected function getPathPermalink()
85
    {
86
        // Remove the protocol of the path, if there is one and prepend a '/' to the beginning
87 3
        $cleanPath = preg_replace('/[\w|\d]+:\/\//', '', $this->getRelativeFilePath());
88 3
        $cleanPath = ltrim($cleanPath, DIRECTORY_SEPARATOR);
89
90
        // Handle vfs:// paths by replacing their forward slashes with the OS appropriate directory separator
91 3
        if (DIRECTORY_SEPARATOR !== '/')
92
        {
93
            $cleanPath = str_replace('/', DIRECTORY_SEPARATOR, $cleanPath);
94
        }
95
96
        // Check the first folder and see if it's a data folder (starts with an underscore) intended for stakx
97 3
        $folders = explode(DIRECTORY_SEPARATOR, $cleanPath);
98
99 3
        if (substr($folders[0], 0, 1) === '_')
100
        {
101 1
            array_shift($folders);
102
        }
103
104 3
        $cleanPath = implode(DIRECTORY_SEPARATOR, $folders);
105
106 3
        return $cleanPath;
107
    }
108
109
    /**
110
     * Sanitize a permalink to remove unsupported characters or multiple '/' and replace spaces with hyphens.
111
     *
112
     * @param string $permalink A permalink
113
     *
114
     * @return string $permalink The sanitized permalink
115
     */
116 39
    protected function sanitizePermalink($permalink)
117
    {
118
        // Remove multiple '/' together
119 39
        $permalink = preg_replace('/\/+/', '/', $permalink);
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $permalink. This often makes code more readable.
Loading history...
120
121
        // Replace all spaces with hyphens
122 39
        $permalink = str_replace(' ', '-', $permalink);
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $permalink. This often makes code more readable.
Loading history...
123
124
        // Remove all disallowed characters
125 39
        $permalink = preg_replace('/[^0-9a-zA-Z-_\/\\\.]/', '', $permalink);
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $permalink. This often makes code more readable.
Loading history...
126
127
        // Handle unnecessary extensions
128 39
        $extensionsToStrip = array('twig');
129
130 39
        if (in_array($this->fs->getExtension($permalink), $extensionsToStrip))
131
        {
132 4
            $permalink = $this->fs->removeExtension($permalink);
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $permalink. This often makes code more readable.
Loading history...
133
        }
134
135
        // Remove any special characters before a sane value
136 39
        $permalink = preg_replace('/^[^0-9a-zA-Z-_]*/', '', $permalink);
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $permalink. This often makes code more readable.
Loading history...
137
138
        // Convert permalinks to lower case
139 39
        if (!Service::getParameter('build.preserveCase'))
140
        {
141 39
            $permalink = mb_strtolower($permalink, 'UTF-8');
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $permalink. This often makes code more readable.
Loading history...
142
        }
143
144 39
        return $permalink;
145
    }
146
147
    /**
148
     * Evaluate the FrontMatter for the document.
149
     *
150
     * This FrontMatter can be the user-defined FrontMatter in a FrontMatterDocument but it can also be used as internal
151
     * settings used for objects that do not have user-defined FrontMatter such as DataItems.
152
     *
153
     * @param array $variables
154
     *
155
     * @return void
156
     */
157
    abstract public function evaluateFrontMatter($variables = array());
158
159
    /**
160
     * @return void
161
     */
162
    abstract public function buildPermalink($force = false);
163
164
    /**
165
     * If a document has extra redirects defined in a special manner, overload this function.
166
     */
167 13
    public function handleSpecialRedirects()
168
    {
169 13
    }
170
}
171