Test Failed
Push — master ( 7c77cf...a1eff0 )
by Josh
03:08
created

Blendable::revertBlend()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 5
c 0
b 0
f 0
dl 0
loc 9
rs 10
cc 3
nc 2
nop 0
1
<?php
2
/**
3
 * Created by PhpStorm.
4
 * User: joshgulledge
5
 * Date: 3/5/18
6
 * Time: 11:14 AM
7
 */
8
9
namespace LCI\Blend\Blendable;
10
11
use LCI\Blend\Blender;
12
use LCI\Blend\Exception\BlendableException;
0 ignored issues
show
Bug introduced by
The type LCI\Blend\Exception\BlendableException 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...
13
14
abstract class Blendable implements BlendableInterface
15
{
16
    /** @var  \modx */
0 ignored issues
show
Bug introduced by
The type modx 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...
17
    protected $modx;
18
19
    /** @var  Blender */
20
    protected $blender;
21
22
    /** @var string ~ blend or revert */
23
    protected $type = 'blend';
24
25
    /** @var string  */
26
    protected $opt_cache_key = '';
27
28
    /** @var array  */
29
    protected $seedCacheOptions = [];
30
31
    /** @var array  */
32
    protected $historyCacheOptions = [];
33
34
    /** @var string */
35
    protected $seeds_dir = '';
36
37
    /** @var int $cache_life in seconds, 0 is forever */
38
    protected $cache_life = 0;
39
40
    /** @var bool  */
41
    protected $error = false;
42
43
    /** @var array  */
44
    protected $error_messages = [];
45
46
    /** @var null|\xPDOSimpleObject  */
0 ignored issues
show
Bug introduced by
The type xPDOSimpleObject 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...
47
    protected $xPDOSimpleObject = null;
48
49
    /** @var string ex: modResource */
50
    protected $xpdo_simple_object_class = '';
51
52
    /** @var string  */
53
    protected $unique_key_column = 'name';
54
55
    /** @var array set when a change of name/alias has been done */
56
    protected $unique_key_history = [];
57
58
    /** @var array ~ this should match data to be inserted via xPDO, ex [column_name => value, ...] */
59
    protected $blendable_xpdo_simple_object_data = [
60
        'name' => ''
61
    ];
62
63
    /** @var array ~ ['setMethodName' => 'setMethodActualName', 'setDoNotUseMethod' => false] overwrite in child classes */
64
    protected $load_from_array_aliases = [];
65
66
    /** @var array ~ list any fields/columns to be ignored on making seeds, like id */
67
    protected $ignore_seed_fields = ['id'];
68
69
    /** @var array ~ xPDOSimpleObject->fromArray() */
70
    protected $current_xpdo_simple_object_data = [];
71
72
    /** @var array  */
73
    protected $related_data = [];
74
75
    /** @var bool  */
76
    protected $exists = false;
77
78
    /** @var bool  */
79
    protected $debug = false;
80
81
    /**
82
     * Blendable constructor.
83
     *
84
     * @param \modx $modx
85
     * @param Blender $blender
86
     * @param string|array $unique_value
87
     */
88
    public function __construct(\modx $modx, Blender $blender, $unique_value = '')
89
    {
90
        $this->modx = $modx;
91
        $this->blender = $blender;
92
        if (method_exists($this, 'loadProperties')) {
93
            $this->loadProperties();
94
        }
95
96
        $this->seedCacheOptions = [
97
            \xPDO::OPT_CACHE_KEY => $this->opt_cache_key,
0 ignored issues
show
Bug introduced by
The type xPDO 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...
98
            \xPDO::OPT_CACHE_PATH => $this->blender->getSeedsPath()
99
        ];
100
101
        $this->historyCacheOptions = [
102
            \xPDO::OPT_CACHE_KEY => $this->opt_cache_key,
103
            \xPDO::OPT_CACHE_PATH => $this->blender->getHistoryPath()
104
        ];
105
106
        $this->setUniqueCriteria($unique_value);
107
        if (!empty($unique_value)) {
108
            $this->loadObject();
109
        }
110
    }
111
112
    /**
113
     * @return bool
114
     */
115
    public function isDebug()
116
    {
117
        return $this->debug;
118
    }
119
120
    /**
121
     * @param bool $debug
122
     *
123
     * @return $this
124
     */
125
    public function setDebug($debug)
126
    {
127
        $this->debug = $debug;
128
        return $this;
129
    }
130
131
    /**
132
     * @return string
133
     */
134
    public function getSeedsDir()
135
    {
136
        return $this->seeds_dir;
137
    }
138
139
    /**
140
     * @param string $dir ~ will be the directory name for seeds and history
141
     *
142
     * @return $this
143
     */
144
    public function setSeedsDir($dir)
145
    {
146
        $this->seeds_dir = (string)$dir;
147
        if (!empty($this->seeds_dir)) {
148
            $this->seedCacheOptions[\xPDO::OPT_CACHE_PATH] = $this->blender->getSeedsPath().$dir.'/';
149
            $this->historyCacheOptions[\xPDO::OPT_CACHE_PATH] = $this->blender->getHistoryPath().$dir.'/';
150
        }
151
        return $this;
152
    }
153
154
    /**
155
     * @return bool
156
     */
157
    public function isExists()
158
    {
159
        return $this->exists;
160
    }
161
162
    /**
163
     * @return bool
164
     */
165
    public function isError()
166
    {
167
        return $this->error;
168
    }
169
170
    /**
171
     * @return array
172
     */
173
    public function getErrorMessages()
174
    {
175
        return $this->error_messages;
176
    }
177
178
    /**
179
     * @param string $type ~ seed or revert
180
     * @return string
181
     */
182
    public function getSeedKey($type = 'seed')
183
    {
184
        $name = $this->blendable_xpdo_simple_object_data[$this->unique_key_column];
185
        if (method_exists($this, 'getFieldName')) {
186
            $name = $this->getFieldName();
187
        }
188
        $key = $this->blender->getSeedKeyFromName($name);
189
190
        switch ($type) {
191
            case 'revert':
192
                $seed_key = 'revert-'.$key;
193
                break;
194
195
            case 'seed':
196
                // no break
197
            default:
198
                $seed_key = $key;
199
        }
200
201
        return $seed_key;
202
    }
203
204
    /**
205
     * @return null|\xPDOSimpleObject
206
     */
207
    public function getXPDOSimpleObject()
208
    {
209
        return $this->xPDOSimpleObject;
210
    }
211
212
    /**
213
     * @param array $data ~ must be in the format: array('columns' => [], 'primaryKeyHistory' => [], 'related' => [])
214
     * @param bool $overwrite
215
     * @return bool
216
     */
217
    public function blendFromArray($data, $overwrite = false)
218
    {
219
        if (isset($data['columns'])) {
220
            $this->blendable_xpdo_simple_object_data = $data['columns'];
221
        }
222
        if (isset($data['primaryKeyHistory']) && $data['primaryKeyHistory']) {
223
            $this->unique_key_history = $data['primaryKeyHistory'];
224
        } else {
225
            $this->unique_key_history = [];
226
        }
227
228
        if (isset($data['related']) && $data['related']) {
229
            $this->related_data = $data['related'];
230
        } else {
231
            $this->related_data = [];
232
        }
233
234
        return $this->blend($overwrite);
235
    }
236
    /**
237
     * @param string $seed_key
238
     * @param bool $overwrite
239
     *
240
     * @return bool
241
     */
242
    public function blendFromSeed($seed_key, $overwrite = false)
243
    {
244
        $this->loadObjectDataFromSeed($seed_key);
245
        return $this->blend($overwrite);
246
    }
247
248
    /**
249
     * @param bool $overwrite
250
     *
251
     * @return bool
252
     */
253
    public function blend($overwrite = false)
254
    {
255
        if ($this->type == 'blend') {
256
            /** @var \LCI\Blend\Blendable\Blendable $currentVersion */
257
            $currentVersion = $this->getCurrentVersion();
258
            $currentVersion
259
                ->setRelatedData($this->related_data)
260
                ->makeHistory();
261
        }
262
263
        $this->modx->invokeEvent(
264
            'OnBlendBeforeSave',
265
            [
266
                'blender' => $this->blender,
267
                'blendable' => $this,
268
                'data' => &$this->blendable_xpdo_simple_object_data,
269
                'type' => $this->type,
270
                'xPDOClass' => $this->xpdo_simple_object_class,
271
                'xPDOSimpleObject' => &$this->xPDOSimpleObject
272
            ]
273
        );
274
275
        $save = $this->save($overwrite);
276
277
        if ($save) {
278
            $this->modx->invokeEvent(
279
                'OnBlendAfterSave',
280
                [
281
                    'blender' => $this->blender,
282
                    'blendable' => $this,
283
                    'data' => &$this->blendable_xpdo_simple_object_data,
284
                    'type' => $this->type,
285
                    'xPDOClass' => $this->xpdo_simple_object_class,
286
                    'xPDOSimpleObject' => &$this->xPDOSimpleObject
287
                ]
288
            );
289
        }
290
291
        return $save;
292
    }
293
294
    /**
295
     * @param bool $make_revert_seed
296
     * @return bool
297
     */
298
    public function delete($make_revert_seed = true)
299
    {
300
        if ($make_revert_seed) {
301
            $this->makeHistory();
302
        }
303
        $removed = false;
304
        if (!is_object($this->xPDOSimpleObject)) {
305
            $this->blender->out($this->blendable_xpdo_simple_object_data[$this->unique_key_column].' of xPDO class '.
306
                $this->xpdo_simple_object_class.' was not found, could not be removed/deleted', true);
0 ignored issues
show
Bug introduced by
true of type true is incompatible with the type integer expected by parameter $verbose of LCI\Blend\Blender::out(). ( Ignorable by Annotation )

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

306
                $this->xpdo_simple_object_class.' was not found, could not be removed/deleted', /** @scrutinizer ignore-type */ true);
Loading history...
307
308
        } elseif ($this->xPDOSimpleObject->remove()) {
309
            $this->onDeleteRevertRelatedPieces();
310
            if ($this->isDebug()) {
311
                $this->blender->out($this->blendable_xpdo_simple_object_data[$this->unique_key_column].' has been removed/deleted');
312
            }
313
            $removed = true;
314
315
        } else {
316
            if ($this->isDebug()) {
317
                $this->blender->out($this->blendable_xpdo_simple_object_data[$this->unique_key_column].' did not remove/delete', true);
318
            }
319
        }
320
321
        return $removed;
322
    }
323
324
    /**
325
     * @return bool
326
     */
327
    public function revertBlend()
328
    {
329
        $seed_key = $this->getSeedKey('revert');
330
        $this->type = 'revert';
331
        if (!$this->loadObjectDataFromHistorySeed($seed_key) || !$this->blendable_xpdo_simple_object_data) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->blendable_xpdo_simple_object_data 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...
332
            return $this->delete(false);
333
        }
334
335
        return $this->blend(true);
336
    }
337
338
    /**
339
     * @return string ~ the related seed key
340
     */
341
    public function seed()
342
    {
343
        // No IDs! must get the alias and get a seed key,
344
        $seed_key = $this->getSeedKey();
345
346
        $data = $this->seedToArray('seed', $seed_key);
347
348
        // now cache it:
349
        $this->modx->cacheManager->set(
350
            $seed_key,
351
            $data,
352
            $this->cache_life,
353
            $this->seedCacheOptions
354
        );
355
356
        return $seed_key;
357
    }
358
359
    /**
360
     * @return string ~ the related seed key
361
     */
362
    public function makeHistory()
363
    {
364
        $seed_key = $this->getSeedKey('revert');
365
366
        $data = $this->seedToArray('revert', $seed_key);
367
368
        // now cache it:
369
        $this->modx->cacheManager->set(
370
            $seed_key,
371
            $data,
372
            $this->cache_life,
373
            $this->historyCacheOptions
374
        );
375
376
        return $seed_key;
377
    }
378
379
    /**
380
     * @param string $type ~ seed or revert
381
     * @param string $seed_key
382
     * @return array
383
     */
384
    public function seedToArray($type = 'seed', $seed_key = '')
385
    {
386
        if (is_object($this->xPDOSimpleObject)) {
387
            $this->current_xpdo_simple_object_data = $this->xPDOSimpleObject->toArray();
388
389
            foreach ($this->current_xpdo_simple_object_data as $column => $value) {
390
                if (in_array($column, $this->ignore_seed_fields)) {
391
                    continue;
392
                }
393
                // Any child class can create a seed method, an example for modResource:
394
                // seedTemplate(1) and would return the string name
395
                $method = 'seed'.$this->makeStudyCase($column);
396
                if (method_exists($this, $method)) {
397
                    $value = $this->$method($value);
398
                }
399
                $this->blendable_xpdo_simple_object_data[$column] = $value;
400
            }
401
402
            $this->seedRelated($type);
403
404
            $data = [
405
                'columns' => $this->blendable_xpdo_simple_object_data,
406
                'primaryKeyHistory' => $this->unique_key_history,
407
                'related' => $this->related_data
408
            ];
409
410
        } elseif ($type == 'revert') {
411
412
            $data = [
413
                'columns' => false,
414
                'primaryKeyHistory' => [],
415
                'related' => []
416
            ];
417
418
            if ($this->isDebug()) {
419
                $this->blender->out('Data not found to make seed: '.$seed_key);
420
            }
421
422
        } elseif ($type == 'seed') {
423
            if ($this->isDebug()) {
424
                $this->blender->out('Data not found to make seed: '.$seed_key);
425
            }
426
        }
427
428
        // https://docs.modx.com/revolution/2.x/developing-in-modx/other-development-resources/class-reference/modx/modx.invokeevent
429
        $this->modx->invokeEvent(
430
            'OnBlendSeed',
431
            [
432
                'blender' => $this->blender,
433
                'blendable' => $this,
434
                'type' => $type,
435
                'xPDOClass' => $this->xpdo_simple_object_class,
436
                'xPDOSimpleObject' => &$this->xPDOSimpleObject,
437
                'data' => &$data
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $data does not seem to be defined for all execution paths leading up to this point.
Loading history...
438
            ]
439
        );
440
441
        return $data;
442
    }
443
444
    /**
445
     * @param bool $overwrite
446
     *
447
     * @return bool
448
     */
449
    protected function save($overwrite = false)
450
    {
451
        $saved = false;
452
453
        if (is_object($this->xPDOSimpleObject)) {
454
            if (!$overwrite) {
455
                $this->error = true;
456
                $this->error_messages['exits'] = $this->xpdo_simple_object_class.': '.
457
                    $this->blendable_xpdo_simple_object_data[$this->unique_key_column].' already exists ';
458
                return $saved;
459
            }
460
        } else {
461
            $this->xPDOSimpleObject = $this->modx->newObject($this->xpdo_simple_object_class);
462
        }
463
464
        $this->xPDOSimpleObject->set($this->unique_key_column, $this->blendable_xpdo_simple_object_data[$this->unique_key_column]);
465
466
        foreach ($this->blendable_xpdo_simple_object_data as $column => $value) {
467
            // Any child class can create a convert method, an example for modResource:
468
            // convertTemplate('String name') and would return the numeric ID
469
            $method = 'convert'.$this->makeStudyCase($column);
470
            if (method_exists($this, $method)) {
471
                $value = $this->$method($value);
472
            }
473
            $this->xPDOSimpleObject->set($column, $value);
474
        }
475
476
        if (method_exists($this, 'getPropertiesData')) {
477
            $this->xPDOSimpleObject->set('properties', $this->getPropertiesData());
478
        }
479
480
        $this->attachRelatedPieces();
481
482
        if ($this->xPDOSimpleObject->save()) {
483
            $this->attachRelatedPiecesAfterSave();
484
            if ($this->isDebug()) {
485
                $this->blender->out($this->blendable_xpdo_simple_object_data[$this->unique_key_column].' has been installed/saved');
486
            }
487
            $saved = true;
488
489
        } else {
490
            if ($this->isDebug()) {
491
                $this->blender->out($this->blendable_xpdo_simple_object_data[$this->unique_key_column].' did not install/update', true);
0 ignored issues
show
Bug introduced by
true of type true is incompatible with the type integer expected by parameter $verbose of LCI\Blend\Blender::out(). ( Ignorable by Annotation )

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

491
                $this->blender->out($this->blendable_xpdo_simple_object_data[$this->unique_key_column].' did not install/update', /** @scrutinizer ignore-type */ true);
Loading history...
492
            }
493
494
        }
495
496
        return $saved;
497
    }
498
499
    protected function getUniqueCriteria()
500
    {
501
        return [
502
            $this->unique_key_column => $this->blendable_xpdo_simple_object_data[$this->unique_key_column]
503
        ];
504
    }
505
506
    /**
507
     * @param string|array $criteria
508
     */
509
    protected function setUniqueCriteria($criteria)
510
    {
511
        $this->blendable_xpdo_simple_object_data[$this->unique_key_column] = $criteria;
512
    }
513
514
    /**
515
     * Will load an existing xPDOSimpleObject if it exists, child class needs to class this one
516
     * @return $this
517
     */
518
    protected function loadObject()
519
    {
520
        $this->xPDOSimpleObject = $this->modx->getObject($this->xpdo_simple_object_class, $this->getUniqueCriteria());
521
522
        if (is_object($this->xPDOSimpleObject)) {
523
            $this->exists = true;
524
            $this->current_xpdo_simple_object_data = $this->xPDOSimpleObject->toArray();
525
            $this->loadFromArray($this->current_xpdo_simple_object_data);
526
            // load related data:
527
            $this->loadRelatedData();
528
        }
529
530
        return $this;
531
    }
532
533
    /**
534
     * @param array $data ~ convert the db data object to blend portable data
535
     *
536
     * @return $this
537
     */
538
    protected function loadFromArray($data = [])
539
    {
540
        foreach ($data as $column => $value) {
541
            $method_name = 'seed'.$this->makeStudyCase($column);
542
543
            if (method_exists($this, $method_name) && !is_null($value)) {
544
                if ($this->isDebug()) {
545
                    $this->blender->out(__METHOD__.' call: '.$method_name.' V: '.$value);
546
                }
547
                $value = $this->$method_name($value);
548
            }
549
550
            $method_name = 'setField'.$this->makeStudyCase($column);
551
552
            if (isset($this->load_from_array_aliases[$method_name])) {
553
                $method_name = $this->load_from_array_aliases[$method_name];
554
555
                if (!$method_name) {
556
                    continue;
557
                }
558
            }
559
560
            if (method_exists($this, $method_name) && !is_null($value)) {
561
                if ($this->isDebug()) {
562
                    $this->blender->out(__METHOD__.' call: '.$method_name.' V: '.$value);
563
                }
564
                $this->$method_name($value);
565
                
566
            } elseif ($this->isDebug()) {
567
                $this->blender->out(__METHOD__.' missing: '.$method_name.' V: '.print_r($value, true), true);
0 ignored issues
show
Bug introduced by
true of type true is incompatible with the type integer expected by parameter $verbose of LCI\Blend\Blender::out(). ( Ignorable by Annotation )

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

567
                $this->blender->out(__METHOD__.' missing: '.$method_name.' V: '.print_r($value, true), /** @scrutinizer ignore-type */ true);
Loading history...
568
            }
569
        }
570
571
        return $this;
572
    }
573
574
    /**
575
     * Override in child classes
576
     */
577
    protected function loadRelatedData()
578
    {
579
        $this->modx->invokeEvent(
580
            'OnBlendLoadRelatedData',
581
            [
582
                'blender' => $this->blender,
583
                'blendable' => $this,
584
                'data' => &$this->blendable_xpdo_simple_object_data,
585
                'type' => $this->type,
586
                'xPDOClass' => $this->xpdo_simple_object_class,
587
                'xPDOSimpleObject' => &$this->xPDOSimpleObject
588
            ]
589
        );
590
    }
591
592
    /**
593
     * @param string $seed_key
594
     *
595
     * @return bool|array
596
     * @throws BlendableException
597
     */
598
    protected function loadObjectDataFromSeed($seed_key)
599
    {
600
        $data = $this->modx->cacheManager->get($seed_key, $this->seedCacheOptions);
601
        if ($data == false) {
602
            if ($this->type == 'blend') {
603
                $this->blender->outError('Error: Seed could not be found: '.$seed_key);
604
                throw new BlendableException('Error: Seed could not be found: '.$seed_key);
605
            }
606
607
        } else {
608
            $this->blendable_xpdo_simple_object_data = $data['columns'];
609
            $this->unique_key_history = $data['primaryKeyHistory'];
610
            $this->related_data = $data['related'];
611
        }
612
613
        return $data;
614
    }
615
616
    /**
617
     * @param string $seed_key
618
     * @return mixed
619
     */
620
    protected function loadObjectDataFromHistorySeed($seed_key)
621
    {
622
        $data = $this->modx->cacheManager->get($seed_key, $this->historyCacheOptions);
623
624
        if (is_array($data)) {
625
            $this->blendable_xpdo_simple_object_data = $data['columns'];
626
            $this->unique_key_history = $data['primaryKeyHistory'];
627
            $this->related_data = $data['related'];
628
        }
629
630
        return $data;
631
    }
632
633
    /**
634
     * @param string $name
635
     * @return string
636
     */
637
    protected function makeStudyCase($name)
638
    {
639
        if ($name == 'templatename') {
640
            $name = 'templateName';
641
        }
642
643
        $StudyName = '';
644
        $parts = explode('_', $name);
645
        foreach ($parts as $part) {
646
            $StudyName .= ucfirst($part);
647
        }
648
649
        return $StudyName;
650
    }
651
652
    /**
653
     * This method is called just before blend/save()
654
     */
655
    protected function attachRelatedPieces()
656
    {
657
658
    }
659
660
    /**
661
     * This method is called just after a successful blend/save()
662
     */
663
    protected function attachRelatedPiecesAfterSave()
664
    {
665
666
    }
667
668
    /**
669
     *
670
     */
671
    protected function onDeleteRevertRelatedPieces()
672
    {
673
674
    }
675
676
    /**
677
     * @var string $type blend or revert
678
     */
679
    protected function seedRelated($type = 'blend')
680
    {
681
        // load related data:
682
        $this->loadRelatedData();
683
684
    }
685
686
    /**
687
     * @return array
688
     */
689
    public function getRelatedData()
690
    {
691
        return $this->related_data;
692
    }
693
694
    /**
695
     * @param array $data
696
     *
697
     * @return $this
698
     */
699
    public function setRelatedData($data)
700
    {
701
        $this->related_data = $data;
702
        return $this;
703
    }
704
705
}