/
TrackableTrait.php
90 lines (73 loc) · 2.16 KB
/
TrackableTrait.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
<?php
declare(strict_types=1);
namespace Atk4\Core;
/**
* If class implements that interface and is added into "Container",
* then container will keep track of it. This method can also
* specify desired name of the object.
*/
trait TrackableTrait
{
/** @var object|null Link to (parent) object into which we added this object. */
private $_owner;
/** @var string Name of the object in owner's element array. */
public $shortName;
public function issetOwner(): bool
{
return $this->_owner !== null;
}
public function getOwner(): object
{
return $this->_owner;
}
/**
* @return $this
*/
public function setOwner(object $owner)
{
if ($this->issetOwner()) {
throw new Exception('Owner already set');
}
$this->_owner = $owner;
return $this;
}
/**
* Should be used only when object is cloned.
*
* @return $this
*/
public function unsetOwner()
{
if (!$this->issetOwner()) {
throw new Exception('Owner not set');
}
$this->_owner = null;
return $this;
}
/**
* If name of the object is omitted then it's naturally to name them
* after the class. You can specify a different naming pattern though.
*/
public function getDesiredName(): string
{
// can be anything, but better to build meaningful name
$name = get_debug_type($this);
return trim(preg_replace('~^atk4\\\\[^\\\\]+\\\\|[^0-9a-z\x7f-\xfe]+~s', '_', mb_strtolower($name)), '_');
}
/**
* Removes object from parent, so that PHP's Garbage Collector can
* dispose of it.
*/
public function destroy(): void
{
if ($this->_owner !== null && TraitUtil::hasContainerTrait($this->_owner)) {
$this->_owner->removeElement($this->shortName);
// GC remove reference to app is AppScope in use
if (TraitUtil::hasAppScopeTrait($this) && $this->issetApp()) {
$this->_app = null; // @phpstan-ignore-line
}
// GC remove reference to owner
$this->_owner = null;
}
}
}