1: <?php
2:
3: declare(strict_types=1);
4:
5: namespace Atk4\Core;
6:
7: // !!! INTENDED TO BE REMOVED LATER - ONLY FOR TRAIT IDENTIFICATION PROPERTIES TO INTERFACES MIGRATION !!!
8:
9: final class TraitUtil
10: {
11: /** @var array<class-string, array<string, bool>> */
12: private static $_hasTraitCache = [];
13:
14: private function __construct()
15: {
16: // zeroton
17: }
18:
19: /**
20: * @param object|class-string $class
21: */
22: public static function hasTrait($class, string $traitName): bool
23: {
24: if (is_object($class)) {
25: $class = get_class($class);
26: }
27:
28: if (!isset(self::$_hasTraitCache[$class][$traitName])) {
29: // prevent mass use for other than internal use then we can decide
30: // if we want to keep support this or replace with pure interfaces
31: if (!str_starts_with($traitName, 'Atk4\Core\\')) {
32: throw new Exception(self::class . '::hasTrait() method is not intended for use with other than Atk4\Core\* traits');
33: }
34:
35: $parentClass = get_parent_class($class);
36: if ($parentClass !== false && self::hasTrait($parentClass, $traitName)) {
37: self::$_hasTraitCache[$class][$traitName] = true;
38: } else {
39: $hasTrait = false;
40: foreach (class_uses($class) as $useName) {
41: if ($useName === $traitName || self::hasTrait($useName, $traitName)) {
42: $hasTrait = true;
43:
44: break;
45: }
46: }
47:
48: self::$_hasTraitCache[$class][$traitName] = $hasTrait;
49: }
50: }
51:
52: return self::$_hasTraitCache[$class][$traitName];
53: }
54:
55: // ConfigTrait - not used
56: // DebugTrait - not used
57: // DynamicMethodTrait - not used
58: // StaticAddToTrait - not used
59: // TranslatableTrait - not used
60:
61: public static function hasAppScopeTrait(object $class): bool
62: {
63: return self::hasTrait($class, AppScopeTrait::class);
64: }
65:
66: public static function hasContainerTrait(object $class): bool
67: {
68: return self::hasTrait($class, ContainerTrait::class);
69: }
70:
71: /**
72: * Used in Factory and in ui/View only.
73: */
74: public static function hasDiContainerTrait(object $class): bool
75: {
76: return self::hasTrait($class, DiContainerTrait::class);
77: }
78:
79: /**
80: * Used in DynamicMethodTrait only.
81: */
82: public static function hasHookTrait(object $class): bool
83: {
84: return self::hasTrait($class, HookTrait::class);
85: }
86:
87: public static function hasInitializerTrait(object $class): bool
88: {
89: return self::hasTrait($class, InitializerTrait::class);
90: }
91:
92: public static function hasNameTrait(object $class): bool
93: {
94: return self::hasTrait($class, NameTrait::class);
95: }
96:
97: public static function hasTrackableTrait(object $class): bool
98: {
99: return self::hasTrait($class, TrackableTrait::class);
100: }
101: }
102: