1: <?php
2:
3: declare(strict_types=1);
4:
5: namespace Atk4\Core;
6:
7: /**
8: * Object with this trait will have it's init() method executed
9: * automatically when initialized through add().
10: */
11: trait InitializerTrait
12: {
13: /** @var bool */
14: private $_initialized = false;
15:
16: /**
17: * Initialize object. Always call parent::init(). Do not call directly.
18: */
19: protected function init(): void
20: {
21: if ($this->isInitialized()) {
22: throw (new Exception('Object already initialized'))
23: ->addMoreInfo('this', $this);
24: }
25: $this->_initialized = true;
26: }
27:
28: public function isInitialized(): bool
29: {
30: return $this->_initialized;
31: }
32:
33: public function assertIsInitialized(): void
34: {
35: if (!$this->isInitialized()) {
36: throw new Exception('Object was not initialized');
37: }
38: }
39:
40: /**
41: * Do not call directly.
42: */
43: public function invokeInit(): void
44: {
45: // assert init() method is not declared as public, ie. not easily directly callable by the user
46: if ((new \ReflectionMethod($this, 'init'))->getModifiers() & \ReflectionMethod::IS_PUBLIC) {
47: throw new Exception('Init method must have protected visibility');
48: }
49:
50: $this->init();
51:
52: $this->assertIsInitialized();
53: }
54: }
55: