44
55use Closure ;
66use ReflectionClass ;
7+ use ReflectionFunction ;
78use Modulus \Support \Extendable ;
89use Modulus \Framework \Exceptions \CannotExtendClassException ;
910use Modulus \Framework \Exceptions \ClassDoesNotExistException ;
@@ -32,6 +33,63 @@ public function bind(string $class, string $method, Closure $closure)
3233 return $ class ::bind ($ method , $ closure );
3334 }
3435
36+ /**
37+ * Bind multple methods at the same time
38+ *
39+ * @param string $class
40+ * @param array $methods
41+ * @deprecated
42+ */
43+ public function bindMany (string $ class , array $ methods )
44+ {
45+ /**
46+ * Map through the functions
47+ *
48+ * @param Closure $closure
49+ */
50+ array_map (function ($ closure ) use ($ class ) {
51+
52+ $ info = new ReflectionFunction ($ closure );
53+
54+ $ doc = explode (PHP_EOL , $ info ->getDocComment ());
55+
56+ /**
57+ * Filter out the stuff that's not needed
58+ */
59+ array_filter ($ doc , function ($ comment ) use ($ class , $ closure ) {
60+
61+ /**
62+ * Register a new function if its not commented out
63+ */
64+ if (str_contains ($ comment , '@method ' ) && !str_contains ($ comment , '// ' )) {
65+
66+ /**
67+ * Filter out "*" and "@method"
68+ */
69+ $ filtered = array_diff (
70+ array_filter (explode (' ' , $ comment )
71+ ), ['* ' , '@method ' ]);
72+
73+ /**
74+ * Return the name of the method
75+ */
76+ $ method = array_first ($ filtered , function ($ value ) {
77+ if (ends_with ($ value , '() ' )) return $ value ;
78+ });
79+
80+ /**
81+ * Bind new method to $class
82+ */
83+ if ($ method ) {
84+ $ this ->bind ($ class , substr ($ method , 0 , strlen ($ method ) - 2 ), $ closure );
85+ }
86+
87+ }
88+
89+ });
90+ }, $ methods );
91+ }
92+
3593 /**
3694 * Add custom static function
3795 *
@@ -53,4 +111,82 @@ public function static(string $class, string $method, Closure $closure)
53111
54112 return $ class ::static ($ method , $ closure );
55113 }
114+
115+ /**
116+ * Add custom property
117+ *
118+ * @param string $class
119+ * @param string $property
120+ * @param Closure $closure
121+ * @return mixed
122+ */
123+ public function prop (string $ class , string $ property , Closure $ closure )
124+ {
125+ if (!class_exists ($ class )) throw new ClassDoesNotExistException ("Class {$ class } does not exist " );
126+
127+ if (!in_array (
128+ Extendable::class,
129+ array_keys ((new ReflectionClass ($ class ))->getTraits ()))
130+ ) {
131+ throw new CannotExtendClassException ("Cannot extend \"{$ class }::class \"" );
132+ }
133+
134+ return $ class ::prop ($ property , $ closure );
135+ }
136+
137+ /**
138+ * Add multiple props at the same time
139+ *
140+ * @param string $class
141+ * @param array $props
142+ */
143+ public function hasManyProps (string $ class , array $ props )
144+ {
145+ /**
146+ * Map through the functions
147+ *
148+ * @param Closure $closure
149+ */
150+ array_map (function ($ closure ) use ($ class ) {
151+
152+ $ info = new ReflectionFunction ($ closure );
153+
154+ $ doc = explode (PHP_EOL , $ info ->getDocComment ());
155+
156+ /**
157+ * Filter out the stuff that's not needed
158+ */
159+ array_filter ($ doc , function ($ comment ) use ($ class , $ closure ) {
160+
161+ /**
162+ * Register a new prop if its not commented out
163+ */
164+ if (str_contains ($ comment , '@var ' ) && !str_contains ($ comment , '// ' )) {
165+
166+ /**
167+ * Filter out "*" and "@var"
168+ */
169+ $ filtered = array_diff (
170+ array_filter (explode (' ' , $ comment )
171+ ), ['* ' , '@var ' ]);
172+
173+ /**
174+ * Return the name of the property
175+ */
176+ $ property = array_last ($ filtered , function ($ value ) {
177+ if (starts_with ($ value , '$ ' ) && preg_match ("/[a-z]|[A-Z]/ " , $ value )) return $ value ;
178+ });
179+
180+ /**
181+ * Bind new property to $class
182+ */
183+ if ($ property ) {
184+ $ this ->prop ($ class , substr ($ property , 1 ), $ closure );
185+ }
186+
187+ }
188+
189+ });
190+ }, $ props );
191+ }
56192}
0 commit comments