Completed
Pull Request — master (#421)
by Robbie
02:31
created

BlogObject   A

Complexity

Total Complexity 23

Size/Duplication

Total Lines 221
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 8

Importance

Changes 0
Metric Value
wmc 23
lcom 1
cbo 8
dl 0
loc 221
rs 10
c 0
b 0
f 0

13 Methods

Rating   Name   Duplication   Size   Complexity  
A BlogPosts() 0 8 1
A getCMSFields() 0 15 1
B validate() 0 19 5
A getLink() 0 8 1
A canView() 0 10 2
A canCreate() 0 12 2
A canDelete() 0 10 2
A canEdit() 0 10 2
A onBeforeWrite() 0 7 2
A generateURLSegment() 0 17 3
A getDuplicatesByField() 0 16 2
getListUrlSegment() 0 1 ?
getDuplicateError() 0 1 ?
1
<?php
2
3
namespace SilverStripe\Blog\Model;
4
5
use SilverStripe\Control\Controller;
6
use SilverStripe\Forms\FieldList;
7
use SilverStripe\Forms\Tab;
8
use SilverStripe\Forms\TabSet;
9
use SilverStripe\Forms\TextField;
10
use SilverStripe\ORM\DataList;
11
use SilverStripe\Security\Permission;
12
use SilverStripe\View\Parsers\URLSegmentFilter;
13
14
/**
15
 * An object shared by BlogTag and BlogCategory.
16
 *
17
 * @package silverstripe
18
 * @subpackage blog
19
 */
20
trait BlogObject
21
{
22
    /**
23
     * @return DataList
24
     */
25
    public function BlogPosts()
26
    {
27
        $blogPosts = parent::BlogPosts();
28
29
        $this->extend('updateGetBlogPosts', $blogPosts);
0 ignored issues
show
Bug introduced by
It seems like extend() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
30
31
        return $blogPosts;
32
    }
33
34
    /**
35
     * {@inheritdoc}
36
     */
37
    public function getCMSFields()
38
    {
39
        $fields = TabSet::create(
40
            'Root',
41
            Tab::create(
42
                'Main',
43
                TextField::create('Title', _t(self::class . '.Title', 'Title'))
44
            )
45
        );
46
47
        $fields = FieldList::create($fields);
48
        $this->extend('updateCMSFields', $fields);
0 ignored issues
show
Bug introduced by
It seems like extend() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
49
50
        return $fields;
51
    }
52
53
    /**
54
     * {@inheritdoc}
55
     * @return ValidationResult
56
     */
57
    public function validate()
58
    {
59
        /** @var ValidationResult $validation */
60
        $validation = parent::validate();
61
        if (!$validation->isValid()) {
62
            return $validation;
63
        }
64
65
        $blog = $this->Blog();
0 ignored issues
show
Bug introduced by
It seems like Blog() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
66
        if (!$blog || !$blog->exists()) {
67
            return $validation;
68
        }
69
70
        if ($this->getDuplicatesByField('Title')->count() > 0) {
71
            $validation->addError($this->getDuplicateError(), self::DUPLICATE_EXCEPTION);
72
        }
73
74
        return $validation;
75
    }
76
77
    /**
78
     * Returns a relative link to this category.
79
     *
80
     * @return string
81
     */
82
    public function getLink()
83
    {
84
        return Controller::join_links(
85
            $this->Blog()->Link(),
0 ignored issues
show
Bug introduced by
It seems like Blog() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
86
            $this->getListUrlSegment(),
87
            $this->URLSegment
0 ignored issues
show
Bug introduced by
The property URLSegment does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
88
        );
89
    }
90
91
    /**
92
     * Inherits from the parent blog or can be overwritten using a DataExtension.
93
     *
94
     * @param null|Member $member
95
     *
96
     * @return bool
97
     */
98
    public function canView($member = null)
99
    {
100
        $extended = $this->extendedCan(__FUNCTION__, $member);
0 ignored issues
show
Bug introduced by
It seems like extendedCan() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
101
102
        if ($extended !== null) {
103
            return $extended;
104
        }
105
106
        return $this->Blog()->canView($member);
0 ignored issues
show
Bug introduced by
It seems like Blog() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
107
    }
108
109
    /**
110
     * {@inheritdoc}
111
     */
112
    public function canCreate($member = null, $context = array())
0 ignored issues
show
Unused Code introduced by
The parameter $context is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
113
    {
114
        $extended = $this->extendedCan(__FUNCTION__, $member);
0 ignored issues
show
Bug introduced by
It seems like extendedCan() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
115
116
        if ($extended !== null) {
117
            return $extended;
118
        }
119
120
        $permission = Blog::config()->grant_user_permission;
121
122
        return Permission::checkMember($member, $permission);
123
    }
124
125
    /**
126
     * Inherits from the parent blog or can be overwritten using a DataExtension.
127
     *
128
     * @param null|Member $member
129
     *
130
     * @return bool
131
     */
132
    public function canDelete($member = null)
133
    {
134
        $extended = $this->extendedCan(__FUNCTION__, $member);
0 ignored issues
show
Bug introduced by
It seems like extendedCan() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
135
136
        if ($extended !== null) {
137
            return $extended;
138
        }
139
140
        return $this->Blog()->canDelete($member);
0 ignored issues
show
Bug introduced by
It seems like Blog() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
141
    }
142
143
    /**
144
     * Inherits from the parent blog or can be overwritten using a DataExtension.
145
     *
146
     * @param null|Member $member
147
     *
148
     * @return bool
149
     */
150
    public function canEdit($member = null)
151
    {
152
        $extended = $this->extendedCan(__FUNCTION__, $member);
0 ignored issues
show
Bug introduced by
It seems like extendedCan() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
153
154
        if ($extended !== null) {
155
            return $extended;
156
        }
157
158
        return $this->Blog()->canEdit($member);
0 ignored issues
show
Bug introduced by
It seems like Blog() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
159
    }
160
161
    /**
162
     * {@inheritdoc}
163
     */
164
    protected function onBeforeWrite()
165
    {
166
        parent::onBeforeWrite();
167
        if (empty($this->URLSegment)) {
168
            return $this->generateURLSegment();
169
        }
170
    }
171
172
    /**
173
     * Generates a unique URLSegment from the title.
174
     *
175
     * @param int $increment
176
     *
177
     * @return string
178
     */
179
    public function generateURLSegment($increment = 0)
180
    {
181
        $increment = (int) $increment;
182
        $filter = URLSegmentFilter::create();
183
184
        $this->URLSegment = $filter->filter($this->Title);
0 ignored issues
show
Bug introduced by
The property Title does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
185
186
        if ($increment > 0) {
187
            $this->URLSegment .= '-' . $increment;
188
        }
189
190
        if ($this->getDuplicatesByField('URLSegment')->count() > 0) {
191
            $this->generateURLSegment($increment + 1);
192
        }
193
194
        return $this->URLSegment;
195
    }
196
197
    /**
198
     * Looks for objects o the same type and the same value by the given Field
199
     *
200
     * @param  string $field E.g. URLSegment or Title
201
     * @return DataList
202
     */
203
    protected function getDuplicatesByField($field)
204
    {
205
        $duplicates = DataList::create(self::class)
206
            ->filter(
207
                [
208
                    $field   => $this->$field,
209
                    'BlogID' => (int) $this->BlogID
0 ignored issues
show
Bug introduced by
The property BlogID does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
210
                ]
211
            );
212
213
        if ($this->ID) {
214
            $duplicates = $duplicates->exclude('ID', $this->ID);
0 ignored issues
show
Bug introduced by
The property ID does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
215
        }
216
217
        return $duplicates;
218
    }
219
220
    /**
221
     * This returns the url segment for the listing page.
222
     * eg. 'categories' in /my-blog/categories/category-url
223
     *
224
     * This is not editable at the moment, but a method is being used incase we want
225
     * to make it editable in the future. We can use this method to provide logic
226
     * without replacing multiple areas of the code base. We're also not being opinionated
227
     * about how the segment should be obtained at the moment and allowing for the
228
     * implementation to decide.
229
     *
230
     * @return string
231
     */
232
    abstract protected function getListUrlSegment();
233
234
    /**
235
     * Returns an error message for this object when it tries to write a duplicate.
236
     *
237
     * @return string
238
     */
239
    abstract protected function getDuplicateError();
240
}
241