Completed
Pull Request — master (#421)
by Robbie
03:13 queued 52s
created

BlogObject::getDuplicateError()

Size

Total Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 1
c 0
b 0
f 0
nc 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 ($this->exists() || empty($this->URLSegment)) {
0 ignored issues
show
Bug introduced by
It seems like exists() 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...
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
        // Setting this to on. Because of the UI flow, it would be quite a lot of work
185
        // to support turning this off. (ie. the add by title flow would not work).
186
        // If this becomes a problem we can approach it then.
187
        // @see https://github.com/silverstripe/silverstripe-blog/issues/376
188
        $filter->setAllowMultibyte(true);
189
190
        $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...
191
192
        if ($increment > 0) {
193
            $this->URLSegment .= '-' . $increment;
194
        }
195
196
        if ($this->getDuplicatesByField('URLSegment')->count() > 0) {
197
            $this->generateURLSegment($increment + 1);
198
        }
199
200
        return $this->URLSegment;
201
    }
202
203
    /**
204
     * Looks for objects o the same type and the same value by the given Field
205
     *
206
     * @param  string $field E.g. URLSegment or Title
207
     * @return DataList
208
     */
209
    protected function getDuplicatesByField($field)
210
    {
211
        $duplicates = DataList::create(self::class)
212
            ->filter(
213
                [
214
                    $field   => $this->$field,
215
                    '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...
216
                ]
217
            );
218
219
        if ($this->ID) {
220
            $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...
221
        }
222
223
        return $duplicates;
224
    }
225
226
    /**
227
     * This returns the url segment for the listing page.
228
     * eg. 'categories' in /my-blog/categories/category-url
229
     *
230
     * This is not editable at the moment, but a method is being used incase we want
231
     * to make it editable in the future. We can use this method to provide logic
232
     * without replacing multiple areas of the code base. We're also not being opinionated
233
     * about how the segment should be obtained at the moment and allowing for the
234
     * implementation to decide.
235
     *
236
     * @return string
237
     */
238
    abstract protected function getListUrlSegment();
239
240
    /**
241
     * Returns an error message for this object when it tries to write a duplicate.
242
     *
243
     * @return string
244
     */
245
    abstract protected function getDuplicateError();
246
}
247