[TASK] Harden \TYPO3\CMS\Extbase\Object\ObjectManager
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Classes / Object / ObjectManager.php
1 <?php
2 declare(strict_types = 1);
3
4 namespace TYPO3\CMS\Extbase\Object;
5
6 /*
7 * This file is part of the TYPO3 CMS project.
8 *
9 * It is free software; you can redistribute it and/or modify it under
10 * the terms of the GNU General Public License, either version 2
11 * of the License, or any later version.
12 *
13 * For the full copyright and license information, please read the
14 * LICENSE.txt file that was distributed with this source code.
15 *
16 * The TYPO3 project - inspiring people to share!
17 */
18
19 use TYPO3\CMS\Extbase\Object\Container\Container;
20
21 /**
22 * Implementation of the default Extbase Object Manager
23 */
24 class ObjectManager implements ObjectManagerInterface
25 {
26 /**
27 * @var \TYPO3\CMS\Extbase\Object\Container\Container
28 */
29 protected $objectContainer;
30
31 /**
32 * Constructs a new Object Manager
33 */
34 public function __construct()
35 {
36 $this->objectContainer = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Extbase\Object\Container\Container::class);
37 }
38
39 /**
40 * Serialization (sleep) helper.
41 *
42 * Removes properties of this object from serialization.
43 * This action is necessary, since there might be closures used
44 * in the accordant content objects (e.g. in FLUIDTEMPLATE) which
45 * cannot be serialized. It's fine to reset $this->contentObjects
46 * since elements will be recreated and are just a local cache,
47 * but not required for runtime logic and behaviour.
48 *
49 * @see http://forge.typo3.org/issues/36820
50 * @return array Names of the properties to be serialized
51 * @internal only to be used within Extbase, not part of TYPO3 Core API.
52 */
53 public function __sleep()
54 {
55 // Use get_objects_vars() instead of
56 // a much more expensive Reflection:
57 $properties = get_object_vars($this);
58 unset($properties['objectContainer']);
59 return array_keys($properties);
60 }
61
62 /**
63 * Unserialization (wakeup) helper.
64 *
65 * Initializes the properties again that have been removed by
66 * a call to the __sleep() method on serialization before.
67 *
68 * @see http://forge.typo3.org/issues/36820
69 * @internal only to be used within Extbase, not part of TYPO3 Core API.
70 */
71 public function __wakeup()
72 {
73 $this->__construct();
74 }
75
76 /**
77 * Returns TRUE if an object with the given name is registered
78 *
79 * @param string $objectName Name of the object
80 * @return bool TRUE if the object has been registered, otherwise FALSE
81 * @internal only to be used within Extbase, not part of TYPO3 Core API.
82 */
83 public function isRegistered(string $objectName): bool
84 {
85 return class_exists($objectName, true);
86 }
87
88 /**
89 * Returns a fresh or existing instance of the object specified by $objectName.
90 *
91 * @param string $objectName The name of the object to return an instance of
92 * @param array $constructorArguments
93 * @return object The object instance
94 */
95 public function get(string $objectName, ...$constructorArguments): object
96 {
97 if ($objectName === 'DateTime') {
98 $instance = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance($objectName, ...$constructorArguments);
99 } else {
100 $instance = $this->objectContainer->getInstance($objectName, $constructorArguments);
101 }
102 return $instance;
103 }
104
105 /**
106 * Returns the scope of the specified object.
107 *
108 * @param string $objectName The object name
109 * @return int One of the Container::SCOPE_ constants
110 * @throws \TYPO3\CMS\Extbase\Object\Container\Exception\UnknownObjectException
111 */
112 public function getScope(string $objectName): int
113 {
114 if (!$this->isRegistered($objectName)) {
115 throw new \TYPO3\CMS\Extbase\Object\Container\Exception\UnknownObjectException('Object "' . $objectName . '" is not registered.', 1265367590);
116 }
117 return $this->objectContainer->isSingleton($objectName) ? Container::SCOPE_SINGLETON : Container::SCOPE_PROTOTYPE;
118 }
119
120 /**
121 * Create an instance of $className without calling its constructor
122 *
123 * @param string $className
124 * @return object
125 */
126 public function getEmptyObject(string $className): object
127 {
128 return $this->objectContainer->getEmptyObject($className);
129 }
130 }