1 | <?php |
||||
2 | |||||
3 | namespace SilverStripe\Taxonomy; |
||||
4 | |||||
5 | use Symbiote\GridFieldExtensions\GridFieldOrderableRows; |
||||
6 | use UndefinedOffset\SortableGridField\Forms\GridFieldSortableRows; |
||||
7 | use SilverStripe\ORM\Hierarchy\Hierarchy; |
||||
8 | use SilverStripe\Forms\GridField\GridFieldDeleteAction; |
||||
9 | use SilverStripe\Forms\GridField\GridFieldAddExistingAutocompleter; |
||||
10 | use SilverStripe\Forms\NumericField; |
||||
11 | use SilverStripe\Security\Permission; |
||||
12 | use SilverStripe\ORM\DataObject; |
||||
13 | use SilverStripe\Security\PermissionProvider; |
||||
14 | |||||
15 | /** |
||||
16 | * Represents a single taxonomy term. Can be re-ordered in the CMS, and the default sorting is to use the order as |
||||
17 | * specified in the CMS. |
||||
18 | * |
||||
19 | * @method TaxonomyTerm Parent() |
||||
20 | * @package taxonomy |
||||
21 | */ |
||||
22 | class TaxonomyTerm extends DataObject implements PermissionProvider |
||||
23 | { |
||||
24 | private static $table_name = 'TaxonomyTerm'; |
||||
25 | |||||
26 | private static $db = array( |
||||
0 ignored issues
–
show
introduced
by
Loading history...
|
|||||
27 | 'Name' => 'Varchar(255)', |
||||
28 | 'Sort' => 'Int' |
||||
29 | ); |
||||
30 | |||||
31 | private static $has_many = array( |
||||
0 ignored issues
–
show
|
|||||
32 | 'Children' => TaxonomyTerm::class |
||||
33 | ); |
||||
34 | |||||
35 | private static $has_one = array( |
||||
0 ignored issues
–
show
|
|||||
36 | 'Parent' => TaxonomyTerm::class, |
||||
37 | 'Type' => TaxonomyType::class |
||||
38 | ); |
||||
39 | |||||
40 | private static $extensions = array( |
||||
0 ignored issues
–
show
|
|||||
41 | Hierarchy::class |
||||
42 | ); |
||||
43 | |||||
44 | private static $casting = array( |
||||
0 ignored issues
–
show
|
|||||
45 | 'TaxonomyName' => 'Text' |
||||
46 | ); |
||||
47 | |||||
48 | private static $default_sort = 'Sort'; |
||||
0 ignored issues
–
show
|
|||||
49 | |||||
50 | private static $summary_fields = array( |
||||
51 | 'Name' => 'Name', |
||||
52 | 'Type.Name' => 'Type' |
||||
53 | ); |
||||
54 | |||||
55 | public function getCMSFields() |
||||
56 | { |
||||
57 | $fields = parent::getCMSFields(); |
||||
58 | |||||
59 | // For now moving taxonomy terms is not supported. |
||||
60 | $fields->removeByName('ParentID'); |
||||
61 | $fields->removeByName('Sort'); |
||||
62 | |||||
63 | // Child taxonomy terms don't need to choose a type, it is inherited |
||||
64 | if ($this->getTaxonomy() !== $this) { |
||||
65 | $fields->removeByName('TypeID'); |
||||
66 | } |
||||
67 | |||||
68 | $childrenGrid = $fields->dataFieldByName('Children'); |
||||
69 | if ($childrenGrid) { |
||||
0 ignored issues
–
show
|
|||||
70 | $deleteAction = $childrenGrid->getConfig()->getComponentByType(GridFieldDeleteAction::class); |
||||
71 | $addExistingAutocompleter = $childrenGrid |
||||
72 | ->getConfig() |
||||
73 | ->getComponentByType(GridFieldAddExistingAutocompleter::class); |
||||
74 | |||||
75 | $childrenGrid->getConfig()->removeComponent($addExistingAutocompleter); |
||||
76 | $childrenGrid->getConfig()->removeComponent($deleteAction); |
||||
77 | $childrenGrid->getConfig()->addComponent(new GridFieldDeleteAction(false)); |
||||
78 | |||||
79 | // Setup sorting of TaxonomyTerm siblings, and fall back to a manual NumericField if no sorting is possible |
||||
80 | if (class_exists(GridFieldOrderableRows::class)) { |
||||
81 | $childrenGrid->getConfig()->addComponent(GridFieldOrderableRows::create('Sort')); |
||||
82 | } elseif (class_exists(GridFieldSortableRows::class)) { |
||||
83 | $childrenGrid->getConfig()->addComponent(new GridFieldSortableRows('Sort')); |
||||
84 | } else { |
||||
85 | $fields->addFieldToTab( |
||||
86 | 'Root.Main', |
||||
87 | NumericField::create('Sort', 'Sort Order') |
||||
88 | ->setDescription( |
||||
89 | 'Enter a whole number to sort this term among siblings (0 is first in the list)' |
||||
90 | ) |
||||
91 | ); |
||||
92 | } |
||||
93 | } |
||||
94 | |||||
95 | return $fields; |
||||
96 | } |
||||
97 | |||||
98 | /** |
||||
99 | * Get the top-level ancestor which doubles as the taxonomy. |
||||
100 | * |
||||
101 | * @return TaxonomyTerm |
||||
102 | */ |
||||
103 | public function getTaxonomy() |
||||
104 | { |
||||
105 | return ($parent = $this->Parent()) && $parent->exists() |
||||
106 | ? $parent->getTaxonomy() |
||||
107 | : $this; |
||||
108 | } |
||||
109 | |||||
110 | /** |
||||
111 | * Gets the name of the top-level ancestor |
||||
112 | * |
||||
113 | * @return string |
||||
114 | */ |
||||
115 | public function getTaxonomyName() |
||||
116 | { |
||||
117 | return $this->getTaxonomy()->Name; |
||||
0 ignored issues
–
show
The property
Name does not exist on SilverStripe\Taxonomy\TaxonomyTerm . Since you implemented __get , consider adding a @property annotation.
Loading history...
|
|||||
118 | } |
||||
119 | |||||
120 | /** |
||||
121 | * Get the type of the top-level ancestor if it is set |
||||
122 | * |
||||
123 | * @return string |
||||
124 | */ |
||||
125 | public function getTaxonomyType() |
||||
126 | { |
||||
127 | $taxonomy = $this->getTaxonomy(); |
||||
128 | if ($taxonomy->Type() && $taxonomy->Type()->exists()) { |
||||
129 | return $taxonomy->Type()->Name; |
||||
130 | } |
||||
131 | return ''; |
||||
132 | } |
||||
133 | |||||
134 | /** |
||||
135 | * Delete all associated children when a taxonomy term is deleted |
||||
136 | * |
||||
137 | * {@inheritDoc} |
||||
138 | */ |
||||
139 | public function onBeforeDelete() |
||||
140 | { |
||||
141 | parent::onBeforeDelete(); |
||||
142 | |||||
143 | foreach ($this->Children() as $term) { |
||||
0 ignored issues
–
show
The method
Children() does not exist on SilverStripe\Taxonomy\TaxonomyTerm . Since you implemented __call , consider adding a @method annotation.
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
144 | /** @var TaxonomyTerm $term */ |
||||
145 | $term->delete(); |
||||
146 | } |
||||
147 | } |
||||
148 | |||||
149 | /** |
||||
150 | * Set the "type" relationship for children to that of the parent (recursively) |
||||
151 | * |
||||
152 | * {@inheritDoc} |
||||
153 | */ |
||||
154 | public function onAfterWrite() |
||||
155 | { |
||||
156 | parent::onAfterWrite(); |
||||
157 | |||||
158 | // Write the parent's type to the current term |
||||
159 | if ($this->Parent()->exists() && $this->Parent()->Type()->exists()) { |
||||
160 | $this->TypeID = $this->Parent()->Type()->ID; |
||||
161 | } |
||||
162 | |||||
163 | // Write the current term's type to all children |
||||
164 | foreach ($this->Children() as $term) { |
||||
165 | /** @var TaxonomyTerm $term */ |
||||
166 | $term->TypeID = $this->Type()->ID; |
||||
167 | $term->write(); |
||||
168 | } |
||||
169 | } |
||||
170 | |||||
171 | public function canView($member = null) |
||||
172 | { |
||||
173 | return true; |
||||
174 | } |
||||
175 | |||||
176 | public function canEdit($member = null) |
||||
177 | { |
||||
178 | $extended = $this->extendedCan(__FUNCTION__, $member); |
||||
179 | if ($extended !== null) { |
||||
180 | return $extended; |
||||
181 | } |
||||
182 | return Permission::check('TAXONOMYTERM_EDIT'); |
||||
183 | } |
||||
184 | |||||
185 | public function canDelete($member = null) |
||||
186 | { |
||||
187 | $extended = $this->extendedCan(__FUNCTION__, $member); |
||||
188 | if ($extended !== null) { |
||||
189 | return $extended; |
||||
190 | } |
||||
191 | return Permission::check('TAXONOMYTERM_DELETE'); |
||||
192 | } |
||||
193 | |||||
194 | public function canCreate($member = null, $context = array()) |
||||
195 | { |
||||
196 | $extended = $this->extendedCan(__FUNCTION__, $member); |
||||
197 | if ($extended !== null) { |
||||
198 | return $extended; |
||||
199 | } |
||||
200 | return Permission::check('TAXONOMYTERM_CREATE'); |
||||
201 | } |
||||
202 | |||||
203 | public function providePermissions() |
||||
204 | { |
||||
205 | return array( |
||||
206 | 'TAXONOMYTERM_EDIT' => array( |
||||
207 | 'name' => _t( |
||||
208 | __CLASS__ . '.EditPermissionLabel', |
||||
209 | 'Edit a taxonomy term' |
||||
210 | ), |
||||
211 | 'category' => _t( |
||||
212 | __CLASS__ . '.Category', |
||||
213 | 'Taxonomy terms' |
||||
214 | ), |
||||
215 | ), |
||||
216 | 'TAXONOMYTERM_DELETE' => array( |
||||
217 | 'name' => _t( |
||||
218 | __CLASS__ . '.DeletePermissionLabel', |
||||
219 | 'Delete a taxonomy term and all nested terms' |
||||
220 | ), |
||||
221 | 'category' => _t( |
||||
222 | __CLASS__ . '.Category', |
||||
223 | 'Taxonomy terms' |
||||
224 | ), |
||||
225 | ), |
||||
226 | 'TAXONOMYTERM_CREATE' => array( |
||||
227 | 'name' => _t( |
||||
228 | __CLASS__ . '.CreatePermissionLabel', |
||||
229 | 'Create a taxonomy term' |
||||
230 | ), |
||||
231 | 'category' => _t( |
||||
232 | __CLASS__ . '.Category', |
||||
233 | 'Taxonomy terms' |
||||
234 | ), |
||||
235 | ) |
||||
236 | ); |
||||
237 | } |
||||
238 | } |
||||
239 |