Completed
Branch 1.3 (ca63b5)
by Morven
03:44
created

LineItem::onAfterWrite()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 15
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 9
nc 4
nop 0
dl 0
loc 15
rs 9.9666
c 0
b 0
f 0

1 Method

Rating   Name   Duplication   Size   Complexity  
A LineItem::canCreate() 0 8 3
1
<?php
2
3
namespace SilverCommerce\OrdersAdmin\Model;
4
5
use SilverStripe\i18n\i18n;
6
use SilverStripe\ORM\DataObject;
7
use SilverStripe\Forms\FieldList;
8
use SilverStripe\Forms\DropdownField;
9
use SilverStripe\Forms\ReadonlyField;
10
use SilverStripe\SiteConfig\SiteConfig;
11
use SilverCommerce\TaxAdmin\Model\TaxRate;
12
use SilverCommerce\TaxAdmin\Traits\Taxable;
13
use SilverCommerce\TaxAdmin\PricingExtension;
0 ignored issues
show
Bug introduced by
The type SilverCommerce\TaxAdmin\PricingExtension was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
14
use SilverStripe\Forms\HTMLEditor\HTMLEditorField;
15
use SilverStripe\Forms\GridField\GridFieldEditButton;
16
use SilverStripe\Forms\GridField\GridFieldDataColumns;
17
use SilverStripe\ORM\FieldType\DBHTMLText as HTMLText;
18
use SilverCommerce\TaxAdmin\Interfaces\TaxableProvider;
19
use SilverStripe\Forms\GridField\GridFieldAddNewButton;
20
use SilverStripe\Forms\GridField\GridFieldDeleteAction;
21
use Symbiote\GridFieldExtensions\GridFieldEditableColumns;
22
use Symbiote\GridFieldExtensions\GridFieldAddNewInlineButton;
23
use SilverStripe\Forms\GridField\GridFieldAddExistingAutocompleter;
24
25
/**
26
 * A LineItem is a single line item on an order, extimate or even in
27
 * the shopping cart.
28
 *
29
 * An item has a number of fields that describes a product:
30
 *
31
 * - Key: ID used to detect this item
32
 * - Title: Title of the item
33
 * - Content: Description of this object
34
 * - Quantity: Number or items in this order
35
 * - Weight: Weight of this item (unit of measurment is defined globally)
36
 * - TaxRate: Rate of tax for this item (e.g. 20.00 for 20%)
37
 * - ProductClass: ClassName of product that this item is matched against
38
 * - StockID: Unique identifier of this item (used with ProductClass
39
 *            match to a product)
40
 * - Locked: Is this a locked item? Locked items cannot be changed in the
41
 *           shopping cart
42
 * - Deliverable: Is this a product that can be delivered? This can effect
43
 *                delivery options
44
 *
45
 * @author Mo <[email protected]>
46
 */
47
class LineItem extends DataObject implements TaxableProvider
48
{
49
    use Taxable;
0 ignored issues
show
Bug introduced by
The trait SilverCommerce\TaxAdmin\Traits\Taxable requires the property $Rate which is not provided by SilverCommerce\OrdersAdmin\Model\LineItem.
Loading history...
50
51
    private static $table_name = 'LineItem';
52
53
    /**
54
     * The name of the param used on a related product to
55
     * track Stock Levels.
56
     *
57
     * Defaults to StockLevel
58
     *
59
     * @var string
60
     * @config
61
     */
62
    private static $stock_param = "StockLevel";
63
64
    /**
65
     * Standard database columns
66
     *
67
     * @var array
68
     * @config
69
     */
70
    private static $db = [
71
        "Key"           => "Varchar(255)",
72
        "Title"         => "Varchar",
73
        "BasePrice"     => "Decimal(9,3)",
74
        "Price"         => "Currency",
75
        "Quantity"      => "Int",
76
        "StockID"       => "Varchar(100)",
77
        "ProductClass"  => "Varchar",
78
        "Locked"        => "Boolean",
79
        "Stocked"       => "Boolean",
80
        "Deliverable"   => "Boolean"
81
    ];
82
83
    /**
84
     * Foreign key associations in DB
85
     *
86
     * @var array
87
     * @config
88
     */
89
    private static $has_one = [
90
        "Parent"      => Estimate::class,
91
        "Tax"         => TaxRate::class,
92
        "TaxRate"     => TaxRate::class
93
    ];
94
    
95
    /**
96
     * One to many associations
97
     *
98
     * @var array
99
     * @config
100
     */
101
    private static $has_many = [
102
        "Customisations" => LineItemCustomisation::class
103
    ];
104
105
    /**
106
     * Specify default values of a field
107
     *
108
     * @var array
109
     * @config
110
     */
111
    private static $defaults = [
112
        "Quantity"      => 1,
113
        "ProductClass"  => "Product",
114
        "Locked"        => false,
115
        "Stocked"       => false,
116
        "Deliverable"   => true
117
    ];
118
119
    /**
120
     * Function to DB Object conversions
121
     *
122
     * @var array
123
     * @config
124
     */
125
    private static $casting = [
126
        "UnitPrice" => "Currency(9,3)",
127
        "UnitTax" => "Currency(9,3)",
128
        "UnitTotal" => "Currency(9,3)",
129
        "SubTotal" => "Currency(9,3)",
130
        "TaxRate" => "Decimal",
131
        "TaxTotal" => "Currency(9,3)",
132
        "Total" => "Currency(9,3)",
133
        "CustomisationList" => "Text",
134
        "CustomisationAndPriceList" => "Text",
135
    ];
136
137
    /**
138
     * Fields to display in list tables
139
     *
140
     * @var array
141
     * @config
142
     */
143
    private static $summary_fields = [
144
        "Quantity",
145
        "Title",
146
        "StockID",
147
        "BasePrice",
148
        "TaxRateID",
149
        "CustomisationAndPriceList"
150
    ];
151
152
    private static $field_labels = [
153
        "BasePrice"=> "Item Price",
154
        "Price"    => "Item Price",
155
        "TaxID"    => "Tax",
156
        "TaxRateID"=> "Tax",
157
        "CustomisationAndPriceList" => "Customisations"
158
    ];
159
160
    /**
161
     * Get the basic price for this object
162
     *
163
     * @return float
164
     */
165
    public function getBasePrice()
166
    {
167
        return $this->dbObject('BasePrice')->getValue();
168
    }
169
170
    /**
171
     * Return the tax rate for this Object
172
     *
173
     * @return TaxRate
174
     */
175
    public function getTaxRate()
176
    {
177
        return $this->TaxRate();
0 ignored issues
show
Bug introduced by
The method TaxRate() does not exist on SilverCommerce\OrdersAdmin\Model\LineItem. 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 ignore-call  annotation

177
        return $this->/** @scrutinizer ignore-call */ TaxRate();
Loading history...
178
    }
179
180
    /**
181
     * Get the locale from the site
182
     *
183
     * @return string
184
     */
185
    public function getLocale()
186
    {
187
        return i18n::get_locale();
188
    }
189
190
    /**
191
     * Get should this field automatically show the price including TAX?
192
     *
193
     * @return bool
194
     */
195
    public function getShowPriceWithTax()
196
    {
197
        $config = SiteConfig::current_site_config();
198
        $show = $config->ShowPriceAndTax;
199
200
        $result = $this->filterTaxableExtensionResults(
201
            $this->extend("updateShowPriceWithTax", $show)
202
        );
203
204
        if (!empty($result)) {
205
            return (bool)$result;
206
        }
207
208
        return (bool)$show;
209
    }
210
211
    /**
212
     * We don't want to show a tax string on Line Items
213
     *
214
     * @return false
215
     */
216
    public function getShowTaxString()
217
    {
218
        return false;
219
    }
220
221
    /**
222
     * Modify default field scaffolding in admin
223
     *
224
     * @return FieldList
225
     */
226
    public function getCMSFields()
227
    {
228
        $this->beforeUpdateCMSFields(function ($fields) {
229
            $config = SiteConfig::current_site_config();
230
231
            $fields->removeByName("Customisation");
232
233
            $fields->addFieldToTab(
234
                "Root.Main",
235
                ReadonlyField::create("Key"),
236
                "Title"
237
            );
238
239
            $fields->addFieldToTab(
240
                "Root.Main",
241
                DropdownField::create(
242
                    "TaxID",
243
                    $this->fieldLabel("TaxID"),
244
                    $config->TaxRates()->map()
245
                ),
246
                "Weight"
247
            );
248
249
            $fields->addFieldsToTab(
250
                "Root.Description",
251
                [
252
                    HTMLEditorField::create("Content")
253
                        ->addExtraClass("stacked")
254
                ]
255
            );
256
257
            // Change unlink button to remove on customisation
258
            $custom_field = $fields->dataFieldByName("Customisations");
259
260
            if ($custom_field) {
261
                $config = $custom_field->getConfig();
262
                $config
263
                    ->removeComponentsByType(GridFieldDeleteAction::class)
264
                    ->removeComponentsByType(GridFieldDataColumns::class)
265
                    ->removeComponentsByType(GridFieldEditButton::class)
266
                    ->removeComponentsByType(GridFieldAddNewButton::class)
267
                    ->removeComponentsByType(GridFieldAddExistingAutocompleter::class)
268
                    ->addComponents(
269
                        new GridFieldEditableColumns(),
270
                        new GridFieldAddNewInlineButton(),
271
                        new GridFieldEditButton(),
272
                        new GridFieldDeleteAction()
273
                    );
274
                
275
                    $custom_field->setConfig($config);
276
            }
277
        });
278
279
        return parent::getCMSFields();
280
    }
281
    
282
    /**
283
     * Get the price for a single line item (unit), minus any tax
284
     *
285
     * @return float
286
     */
287
    public function getNoTaxPrice()
288
    {
289
        $price = $this->getBasePrice();
290
291
        foreach ($this->Customisations() as $customisation) {
0 ignored issues
show
Bug introduced by
The method Customisations() does not exist on SilverCommerce\OrdersAdmin\Model\LineItem. 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 ignore-call  annotation

291
        foreach ($this->/** @scrutinizer ignore-call */ Customisations() as $customisation) {
Loading history...
292
            $price += $customisation->Price;
293
        }
294
295
        $result = $this->getOwner()->filterTaxableExtensionResults(
0 ignored issues
show
Bug introduced by
The method getOwner() does not exist on SilverCommerce\OrdersAdmin\Model\LineItem. 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 ignore-call  annotation

295
        $result = $this->/** @scrutinizer ignore-call */ getOwner()->filterTaxableExtensionResults(
Loading history...
296
            $this->extend("updateNoTaxPrice", $price)
297
        );
298
299
        if (!empty($result)) {
300
            return $result;
301
        }
302
303
        return $price;
304
    }
305
306
    public function getUnitPrice()
307
    {
308
        return $this->getNoTaxPrice();
309
    }
310
311
    /**
312
     * Get the amount of tax for a single unit of this item
313
     *
314
     * **NOTE** Tax is rounded at the single item price to avoid multiplication
315
     * weirdness. For example 49.995 + 20% is 59.994 for one product,
316
     * but 239.976 for 4 (it should be 239.96)
317
     *
318
     * @return float
319
     */
320
    public function getUnitTax()
321
    {
322
        // Calculate and round tax now to try and minimise penny rounding issues
323
        $total = ($this->UnitPrice / 100) * $this->TaxPercentage;
0 ignored issues
show
Bug Best Practice introduced by
The property TaxPercentage does not exist on SilverCommerce\OrdersAdmin\Model\LineItem. Since you implemented __get, consider adding a @property annotation.
Loading history...
Bug Best Practice introduced by
The property UnitPrice does not exist on SilverCommerce\OrdersAdmin\Model\LineItem. Since you implemented __get, consider adding a @property annotation.
Loading history...
324
325
        $this->extend("updateUnitTax", $total);
326
327
        return $total;
328
    }
329
330
    /**
331
     * Get the total price and tax for a single unit
332
     *
333
     * @return float
334
     */
335
    public function getUnitTotal()
336
    {
337
        $total = $this->UnitPrice + $this->UnitTax;
0 ignored issues
show
Bug Best Practice introduced by
The property UnitPrice does not exist on SilverCommerce\OrdersAdmin\Model\LineItem. Since you implemented __get, consider adding a @property annotation.
Loading history...
Bug Best Practice introduced by
The property UnitTax does not exist on SilverCommerce\OrdersAdmin\Model\LineItem. Since you implemented __get, consider adding a @property annotation.
Loading history...
338
339
        $this->extend("updateUnitTotal", $total);
340
341
        return $total;
342
    }
343
344
    /**
345
     * Get the value of this item, minus any tax
346
     *
347
     * @return float
348
     */
349
    public function getSubTotal()
350
    {
351
        $total = $this->NoTaxPrice * $this->Quantity;
0 ignored issues
show
Bug Best Practice introduced by
The property NoTaxPrice does not exist on SilverCommerce\OrdersAdmin\Model\LineItem. Since you implemented __get, consider adding a @property annotation.
Loading history...
Bug Best Practice introduced by
The property Quantity does not exist on SilverCommerce\OrdersAdmin\Model\LineItem. Since you implemented __get, consider adding a @property annotation.
Loading history...
352
353
        $this->extend("updateSubTotal", $total);
354
355
        return $total;
356
    }
357
358
    /**
359
     * Get the total amount of tax for a single unit of this item
360
     *
361
     * @return float
362
     */
363
    public function getTaxTotal()
364
    {
365
        $total = $this->UnitTax * $this->Quantity;
0 ignored issues
show
Bug Best Practice introduced by
The property UnitTax does not exist on SilverCommerce\OrdersAdmin\Model\LineItem. Since you implemented __get, consider adding a @property annotation.
Loading history...
Bug Best Practice introduced by
The property Quantity does not exist on SilverCommerce\OrdersAdmin\Model\LineItem. Since you implemented __get, consider adding a @property annotation.
Loading history...
366
367
        $this->extend("updateTaxTotal", $total);
368
369
        return $total;
370
    }
371
372
    /**
373
     * Get the value of this item, minus any tax
374
     *
375
     * @return float
376
     */
377
    public function getTotal()
378
    {
379
        $total = $this->SubTotal + $this->TaxTotal;
0 ignored issues
show
Bug Best Practice introduced by
The property SubTotal does not exist on SilverCommerce\OrdersAdmin\Model\LineItem. Since you implemented __get, consider adding a @property annotation.
Loading history...
Bug Best Practice introduced by
The property TaxTotal does not exist on SilverCommerce\OrdersAdmin\Model\LineItem. Since you implemented __get, consider adding a @property annotation.
Loading history...
380
381
        $this->extend("updateTotal", $total);
382
    
383
        return $total;
384
    }
385
386
    /**
387
     * Get an image object associated with this line item.
388
     * By default this is retrieved from the base product.
389
     *
390
     * @return Image | null
0 ignored issues
show
Bug introduced by
The type SilverCommerce\OrdersAdmin\Model\Image was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
391
     */
392
    public function Image()
393
    {
394
        $product = $this->FindStockItem();
395
396
        if ($product && method_exists($product, "SortedImages")) {
397
            return  $product->SortedImages()->first();
398
        } elseif ($product && method_exists($product, "Images")) {
399
            return $product->Images()->first();
400
        } elseif ($product && method_exists($product, "Image") && $product->Image()->exists()) {
401
            return $product->Image();
402
        }
403
    }
404
    
405
    /**
406
     * Provide a string of customisations seperated by a comma but not
407
     * including a price
408
     *
409
     * @return string
410
     */
411
    public function getCustomisationList()
412
    {
413
        $return = [];
414
        $items = $this->Customisations();
415
416
        if ($items && $items->exists()) {
417
            foreach ($items as $item) {
418
                $return[] = $item->Title . ': ' . $item->Value;
419
            }
420
        }
421
422
        $this->extend("updateCustomisationList", $return);
423
424
        return implode(", ", $return);
425
    }
426
427
    /**
428
     * Provide a string of customisations seperated by a comma and
429
     * including a price
430
     *
431
     * @return string
432
     */
433
    public function getCustomisationAndPriceList()
434
    {
435
        $return = [];
436
        $items = $this->Customisations();
437
438
        if ($items && $items->exists()) {
439
            foreach ($items as $item) {
440
                $return[] = $item->Title . ': ' . $item->Value . ' (' . $item->getFormattedPrice() . ')';
441
            }
442
        }
443
444
        $this->extend("updateCustomisationAndPriceList", $return);
445
446
        return implode(", ", $return);
447
    }
448
    
449
    /**
450
     * Get list of customisations rendering into a basic
451
     * HTML string
452
     *
453
     * @return HTMLText
454
     */
455
    public function CustomisationHTML()
456
    {
457
        $return = HTMLText::create();
458
        $items = $this->Customisations();
459
        $html = "";
460
        
461
        if ($items && $items->exists()) {
462
            foreach ($items as $item) {
463
                $html .= $item->Title . ': ' . $item->Value . ";<br/>";
464
            }
465
        }
466
467
        $return->setValue($html);
468
469
        $this->extend("updateCustomisationHTML", $return);
470
471
        return $return;
472
    }
473
        
474
    /**
475
     * Match this item to another object in the Database, by the
476
     * provided details.
477
     *
478
     * @param $relation_name = The class name of the related dataobject
0 ignored issues
show
Documentation Bug introduced by
The doc comment = at position 0 could not be parsed: Unknown type name '=' at position 0 in =.
Loading history...
479
     * @param $relation_col = The column name of the related object
480
     * @param $match_col = The column we use to match the two objects
481
     * @return DataObject
482
     */
483
    public function Match($relation_name = null, $relation_col = "StockID", $match_col = "StockID")
484
    {
485
        // Try to determine relation name
486
        if (!$relation_name && !$this->ProductClass) {
0 ignored issues
show
Bug Best Practice introduced by
The property ProductClass does not exist on SilverCommerce\OrdersAdmin\Model\LineItem. Since you implemented __get, consider adding a @property annotation.
Loading history...
487
            $relation_name = "Product";
488
        } elseif (!$relation_name && $this->ProductClass) {
489
            $relation_name = $this->ProductClass;
490
        }
491
        
492
        return $relation_name::get()
493
            ->filter($relation_col, $this->$match_col)
494
            ->first();
495
    }
496
497
    /**
498
     * Find our original stock item (useful for adding links back to the
499
     * original product).
500
     *
501
     * This function is a synonym for @Link Match (as a result of) merging
502
     * LineItem
503
     *
504
     * @return DataObject
505
     */
506
    public function FindStockItem()
507
    {
508
        return $this->Match();
509
    }
510
511
    /**
512
     * Check stock levels for this item, will return the actual number
513
     * of remaining stock after removing the current quantity
514
     *
515
     * @param $qty The quantity we want to check against
0 ignored issues
show
Bug introduced by
The type SilverCommerce\OrdersAdmin\Model\The was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
516
     * @return Int
517
     */
518
    public function checkStockLevel($qty)
519
    {
520
        $stock_param = $this->config()->get("stock_param");
521
        $item = $this->Match();
522
        $stock = ($item->$stock_param) ? $item->$stock_param : 0;
523
        $return = $stock - $qty;
524
525
        $this->extend("updateCheckStockLevel", $return);
526
        
527
        return $return;
528
    }
529
530
    /**
531
     * Generate a key based on this item and its customisations
532
     *
533
     * @return string
534
     */
535
    public function generateKey()
536
    {
537
        // Generate a unique item key based on the current ID and customisations
538
        $key = base64_encode(
539
            json_encode(
540
                $this->Customisations()->map("Title", "Value")->toArray()
541
            )
542
        );
543
        return $this->StockID . ':' . $key;
0 ignored issues
show
Bug Best Practice introduced by
The property StockID does not exist on SilverCommerce\OrdersAdmin\Model\LineItem. Since you implemented __get, consider adding a @property annotation.
Loading history...
544
    }
545
546
    /**
547
     * Only order creators or users with VIEW admin rights can view
548
     *
549
     * @return Boolean
550
     */
551
    public function canView($member = null, $context = [])
0 ignored issues
show
Unused Code introduced by
The parameter $context is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

551
    public function canView($member = null, /** @scrutinizer ignore-unused */ $context = [])

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

Loading history...
552
    {
553
        $extended = $this->extend('canView', $member);
554
        if ($extended && $extended !== null) {
555
            return $extended;
556
        }
557
558
        return $this->Parent()->canView($member);
0 ignored issues
show
Bug introduced by
The method Parent() does not exist on SilverCommerce\OrdersAdmin\Model\LineItem. 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 ignore-call  annotation

558
        return $this->/** @scrutinizer ignore-call */ Parent()->canView($member);
Loading history...
559
    }
560
561
    /**
562
     * Anyone can create an order item
563
     *
564
     * @return Boolean
565
     */
566
    public function canCreate($member = null, $context = [])
567
    {
568
        $extended = $this->extend('canCreate', $member);
569
        if ($extended && $extended !== null) {
570
            return $extended;
571
        }
572
573
        return true;
574
    }
575
576
    /**
577
     * No one can edit items once they are created
578
     *
579
     * @return Boolean
580
     */
581
    public function canEdit($member = null, $context = [])
0 ignored issues
show
Unused Code introduced by
The parameter $context is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

581
    public function canEdit($member = null, /** @scrutinizer ignore-unused */ $context = [])

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

Loading history...
582
    {
583
        $extended = $this->extend('canEdit', $member);
584
        if ($extended && $extended !== null) {
585
            return $extended;
586
        }
587
588
        return $this->Parent()->canEdit($member);
589
    }
590
591
    /**
592
     * No one can delete items once they are created
593
     *
594
     * @return Boolean
595
     */
596
    public function canDelete($member = null, $context = [])
0 ignored issues
show
Unused Code introduced by
The parameter $context is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

596
    public function canDelete($member = null, /** @scrutinizer ignore-unused */ $context = [])

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

Loading history...
597
    {
598
        $extended = $this->extend('canDelete', $member);
599
        if ($extended && $extended !== null) {
600
            return $extended;
601
        }
602
603
        return $this->Parent()->canEdit($member);
604
    }
605
606
    /**
607
     * Overwrite default duplicate function
608
     *
609
     * @param boolean $doWrite (write the cloned object to DB)
610
     * @return DataObject $clone The duplicated object
611
     */
612
    public function duplicate($doWrite = true, $manyMany = "many_many")
613
    {
614
        $clone = parent::duplicate($doWrite);
615
616
        // Ensure we clone any customisations
617
        if ($doWrite) {
618
            foreach ($this->Customisations() as $customisation) {
619
                $new_item = $customisation->duplicate(false);
620
                $new_item->ParentID = $clone->ID;
621
                $new_item->write();
622
            }
623
        }
624
625
        return $clone;
626
    }
627
628
    /**
629
     * Pre-write tasks
630
     *
631
     * @return void
632
     */
633
    public function onBeforeWrite()
634
    {
635
        parent::onBeforeWrite();
636
        $this->Key = $this->generateKey();
0 ignored issues
show
Bug Best Practice introduced by
The property Key does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
637
    }
638
639
    /**
640
     * Clean up DB on deletion
641
     *
642
     * @return void
643
     */
644
    public function onBeforeDelete()
645
    {
646
        parent::onBeforeDelete();
647
648
        foreach ($this->Customisations() as $customisation) {
649
            $customisation->delete();
650
        }
651
    }
652
}
653