Passed
Push — master ( 009d48...0bee53 )
by Nicolaas
09:28
created

ExternalURL   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 128
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 46
dl 0
loc 128
rs 10
c 0
b 0
f 0
wmc 20

8 Methods

Rating   Name   Duplication   Size   Complexity  
A scaffoldFormField() 0 6 1
A Domain() 0 7 2
A Path() 0 7 2
A forTemplate() 0 7 2
A __construct() 0 3 1
A Nice() 0 15 4
B saveInto() 0 34 7
A NoWWW() 0 4 1
1
<?php
2
3
namespace Sunnysideup\ExternalURLField;
4
5
use SilverStripe\Core\Config\Config;
6
use SilverStripe\ORM\FieldType\DBVarchar;
7
8
class ExternalURL extends DBVarchar
9
{
10
    private static $casting = [
11
        'Domain' => ExternalURL::class,
12
        'URL' => ExternalURL::class,
13
        'Path' => 'Varchar',
14
    ];
15
16
    /**
17
     * 2083 is the lowest common denominator when it comes to url lengths.
18
     * however, 768 allows searching...
19
     *
20
     * @param null|mixed $name
21
     * @param mixed      $size
22
     * @param mixed      $options
23
     */
24
    public function __construct($name = null, $size = 2083, $options = [])
25
    {
26
        parent::__construct($name, $size, $options);
27
    }
28
29
    /**
30
     * Remove ugly parts of a url to make it nice.
31
     */
32
    public function Nice(): string
33
    {
34
        if ($this->value) {
35
            $parts = parse_url($this->URL());
36
            if ($parts) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $parts of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
37
                $remove = ['scheme', 'user', 'pass', 'port', 'query', 'fragment'];
38
                foreach ($remove as $part) {
39
                    unset($parts[$part]);
40
                }
41
            }
42
43
            return rtrim(http_build_url($parts), '/');
44
        }
45
46
        return '';
47
    }
48
49
    /**
50
     * Get just the domain of the url.
51
     */
52
    public function Domain()
53
    {
54
        if ($this->value) {
55
            return parse_url($this->URL(), PHP_URL_HOST);
56
        }
57
58
        return '';
59
    }
60
61
    /**
62
     * Remove the www subdomain, if present.
63
     */
64
    public function NoWWW()
65
    {
66
        //https://stackoverflow.com/questions/23349257/trim-a-full-string-instead-of-using-trim-with-characters
67
        return $url = preg_replace('/^(www\.)*/', '', (string) $this->value);
0 ignored issues
show
Unused Code introduced by
The assignment to $url is dead and can be removed.
Loading history...
68
    }
69
70
    public function Path()
71
    {
72
        if ($this->value) {
73
            return trim((string) parse_url((string) $this->URL(), PHP_URL_PATH), '/');
74
        }
75
76
        return '';
77
    }
78
79
    /**
80
     * Scaffold the ExternalURLField for this ExternalURL.
81
     *
82
     * @param null|mixed $title
83
     * @param null|mixed $params
84
     */
85
    public function scaffoldFormField($title = null, $params = null)
86
    {
87
        $field = new ExternalURLField($this->name, $title);
88
        $field->setMaxLength($this->getSize());
89
90
        return $field;
91
    }
92
93
    public function forTemplate()
94
    {
95
        if ($this->value) {
96
            return (string) $this->URL();
97
        }
98
99
        return '';
100
    }
101
102
    public function saveInto($dataObject)
103
    {
104
        $fieldName = $this->name;
105
        if ($fieldName) {
106
            $url = (string) $this->value;
107
            if (! $url) {
108
                return '';
109
            }
110
            $config = Config::inst()->get(ExternalURLField::class, 'default_config');
111
            $defaults = $config['defaultparts'];
112
            if (! preg_match('#^[a-zA-Z]+://#', $url)) {
113
                $url = $defaults['scheme'] . '://' . $url;
114
            }
115
116
            $parts = parse_url($url);
117
            if (! $parts) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $parts of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
118
                //can't parse url, abort
119
                return '';
120
            }
121
122
            foreach (array_keys($parts) as $part) {
123
                if (true === $config['removeparts'][$part]) {
124
                    unset($parts[$part]);
125
                }
126
            }
127
128
            // this causes errors!
129
            // $parts = array_filter($defaults, fn ($default) => ! isset($parts[$part]));
130
131
            $dataObject->{$fieldName} = rtrim(http_build_url($defaults, $parts), '/');
132
        } else {
133
            $class = static::class;
134
135
            throw new \RuntimeException("DBField::saveInto() Called on a nameless '{$class}' object");
136
        }
137
    }
138
}
139