33namespace Neuron \Mvc \Controllers ;
44
55use League \CommonMark \Exception \CommonMarkException ;
6+ use Neuron \Core \Exceptions \BadRequestMethod ;
7+ use Neuron \Data \Setting \SettingManager ;
68use Neuron \Mvc \Application ;
9+ use Neuron \Mvc \Cache \CacheConfig ;
10+ use Neuron \Mvc \Cache \Exceptions \CacheException ;
11+ use Neuron \Mvc \Cache \Storage \FileCacheStorage ;
12+ use Neuron \Mvc \Cache \ViewCache ;
713use Neuron \Mvc \Responses \HttpResponseStatus ;
814use Neuron \Mvc \Views \Html ;
915use Neuron \Mvc \Views \Json ;
@@ -16,21 +22,30 @@ class Base implements IController
1622{
1723 private Router $ _Router ;
1824
25+ /**
26+ * @param Router $Router
27+ */
1928 public function __construct ( Router $ Router )
2029 {
2130 $ this ->setRouter ( $ Router );
2231 }
2332
2433 /**
25- * @throws \Neuron\Core\Exceptions\NotFound
34+ * @param HttpResponseStatus $ResponseCode
35+ * @param array $Data
36+ * @param string $Page
37+ * @param string $Layout
38+ * @param bool|null $CacheEnabled
39+ * @return string
2640 * @throws CommonMarkException
41+ * @throws \Neuron\Core\Exceptions\NotFound
2742 */
2843 public function renderMarkdown ( HttpResponseStatus $ ResponseCode , array $ Data = [], string $ Page = "index " , string $ Layout = "default " , ?bool $ CacheEnabled = null ) : string
2944 {
3045 @http_response_code ( $ ResponseCode ->value );
3146
32- $ View = ( new Markdown () )
33- ->setController ( ( new \ReflectionClass ( static ::class ) )->getShortName () )
47+ $ View = new Markdown ()
48+ ->setController ( new \ReflectionClass ( static ::class )->getShortName () )
3449 ->setLayout ( $ Layout )
3550 ->setPage ( $ Page )
3651 ->setCacheEnabled ( $ CacheEnabled );
@@ -39,21 +54,32 @@ public function renderMarkdown( HttpResponseStatus $ResponseCode, array $Data =
3954 }
4055
4156 /**
57+ * @param HttpResponseStatus $ResponseCode
58+ * @param array $Data
59+ * @param string $Page
60+ * @param string $Layout
61+ * @param bool|null $CacheEnabled
62+ * @return string
4263 * @throws \Neuron\Core\Exceptions\NotFound
4364 */
4465 public function renderHtml ( HttpResponseStatus $ ResponseCode , array $ Data = [], string $ Page = "index " , string $ Layout = "default " , ?bool $ CacheEnabled = null ) : string
4566 {
4667 @http_response_code ( $ ResponseCode ->value );
4768
48- $ View = ( new Html () )
49- ->setController ( ( new \ReflectionClass ( static ::class ) )->getShortName () )
69+ $ View = new Html ()
70+ ->setController ( new \ReflectionClass ( static ::class )->getShortName () )
5071 ->setLayout ( $ Layout )
5172 ->setPage ( $ Page )
5273 ->setCacheEnabled ( $ CacheEnabled );
5374
5475 return $ View ->render ( $ Data );
5576 }
5677
78+ /**
79+ * @param HttpResponseStatus $ResponseCode
80+ * @param array $Data
81+ * @return string
82+ */
5783 public function renderJson ( HttpResponseStatus $ ResponseCode , array $ Data = [] ): string
5884 {
5985 @http_response_code ( $ ResponseCode ->value );
@@ -63,6 +89,11 @@ public function renderJson( HttpResponseStatus $ResponseCode, array $Data = [] )
6389 return $ View ->render ( $ Data );
6490 }
6591
92+ /**
93+ * @param HttpResponseStatus $ResponseCode
94+ * @param array $Data
95+ * @return string
96+ */
6697 public function renderXml ( HttpResponseStatus $ ResponseCode , array $ Data = [] ): string
6798 {
6899 @http_response_code ( $ ResponseCode ->value );
@@ -90,6 +121,137 @@ public function setRouter( Router $Router ): Base
90121 return $ this ;
91122 }
92123
124+ /**
125+ * Get the controller name for cache key generation.
126+ * Returns the short class name (without namespace).
127+ * This matches how the framework's render methods set the controller name.
128+ *
129+ * @return string The controller class name without namespace
130+ */
131+ protected function getControllerName (): string
132+ {
133+ // Using static::class ensures this returns the actual derived class name
134+ // not "Base", even when called from this base class
135+ return new \ReflectionClass ( static ::class )->getShortName ();
136+ }
137+
138+ /**
139+ * Initialize ViewCache if not already present in Registry.
140+ * This allows controllers to check cache before making expensive API calls.
141+ *
142+ * @return ViewCache|null The ViewCache instance or null if initialization fails
143+ */
144+ protected function initializeViewCache (): ?ViewCache
145+ {
146+ $ Registry = \Neuron \Patterns \Registry::getInstance ();
147+
148+ // Check if cache is already initialized
149+ $ ViewCache = $ Registry ->get ( 'ViewCache ' );
150+ if ( $ ViewCache !== null )
151+ {
152+ return $ ViewCache ;
153+ }
154+
155+ // Try to create cache from settings
156+ $ Settings = $ Registry ->get ( 'Settings ' );
157+ if ( $ Settings === null )
158+ {
159+ return null ;
160+ }
161+
162+ // Handle both SettingManager and ISettingSource
163+ if ( $ Settings instanceof SettingManager )
164+ {
165+ $ SettingSource = $ Settings ->getSource ();
166+ }
167+ else
168+ {
169+ $ SettingSource = $ Settings ;
170+ }
171+
172+ $ Config = CacheConfig::fromSettings ( $ SettingSource );
173+
174+ if ( !$ Config ->isEnabled () )
175+ {
176+ return null ;
177+ }
178+
179+ try
180+ {
181+ $ BasePath = $ Registry ->get ( 'Base.Path ' ) ?? '. ' ;
182+ $ CachePath = $ BasePath . DIRECTORY_SEPARATOR . $ Config ->getCachePath ();
183+
184+ $ Storage = new FileCacheStorage ( $ CachePath );
185+ $ ViewCache = new ViewCache (
186+ $ Storage ,
187+ true ,
188+ $ Config ->getDefaultTtl (),
189+ $ Config
190+ );
191+
192+ $ Registry ->set ( 'ViewCache ' , $ ViewCache );
193+
194+ return $ ViewCache ;
195+ }
196+ catch ( CacheException $ e )
197+ {
198+ // Unable to initialize cache
199+ return null ;
200+ }
201+ }
202+
203+ /**
204+ * Check if view cache exists for the given page and data.
205+ * Initializes ViewCache if needed.
206+ *
207+ * @param string $Page The page/view name
208+ * @param array $Data The data that affects cache key generation
209+ * @return bool True if cache exists, false otherwise
210+ */
211+ protected function hasViewCache ( string $ Page , array $ Data = [] ): bool
212+ {
213+ $ ViewCache = $ this ->initializeViewCache ();
214+
215+ if ( !$ ViewCache || !$ ViewCache ->isEnabled () )
216+ {
217+ return false ;
218+ }
219+
220+ $ CacheKey = $ ViewCache ->generateKey (
221+ $ this ->getControllerName (),
222+ $ Page ,
223+ $ Data
224+ );
225+
226+ return $ ViewCache ->exists ( $ CacheKey );
227+ }
228+
229+ /**
230+ * Get cached view content if available.
231+ * Initializes ViewCache if needed.
232+ *
233+ * @param string $Page The page/view name
234+ * @param array $Data The data that affects cache key generation
235+ * @return string|null The cached content or null if not found
236+ */
237+ protected function getViewCache ( string $ Page , array $ Data = [] ): ?string
238+ {
239+ $ ViewCache = $ this ->initializeViewCache ();
240+
241+ if ( !$ ViewCache || !$ ViewCache ->isEnabled () )
242+ {
243+ return null ;
244+ }
245+
246+ $ CacheKey = $ ViewCache ->generateKey (
247+ $ this ->getControllerName (),
248+ $ Page ,
249+ $ Data
250+ );
251+
252+ return $ ViewCache ->get ( $ CacheKey );
253+ }
254+
93255 /**
94256 * This method registers routes for any of the standard methods that
95257 * are currently implemented in the class.
@@ -103,8 +265,9 @@ public function setRouter( Router $Router ): Base
103265 *
104266 * @param Application $App
105267 * @param string $Route
268+ * @throws BadRequestMethod
106269 */
107- public static function register ( Application $ App , string $ Route = '' )
270+ public static function register ( Application $ App , string $ Route = '' ): void
108271 {
109272 if ( $ Route == '' )
110273 {
@@ -120,7 +283,14 @@ public static function register( Application $App, string $Route = '' )
120283 self ::registerDelete ( $ App ,static ::class, $ Route );
121284 }
122285
123- protected static function registerIndex ( Application $ App , string $ Controller , string $ Route )
286+ /**
287+ * @param Application $App
288+ * @param string $Controller
289+ * @param string $Route
290+ * @return void
291+ * @throws BadRequestMethod
292+ */
293+ protected static function registerIndex ( Application $ App , string $ Controller , string $ Route ): void
124294 {
125295 if ( method_exists ( $ Controller , 'index ' ) )
126296 {
@@ -132,7 +302,14 @@ protected static function registerIndex( Application $App, string $Controller, s
132302 }
133303 }
134304
135- protected static function registerAdd ( Application $ App , string $ Controller , string $ Route )
305+ /**
306+ * @param Application $App
307+ * @param string $Controller
308+ * @param string $Route
309+ * @return void
310+ * @throws BadRequestMethod
311+ */
312+ protected static function registerAdd ( Application $ App , string $ Controller , string $ Route ): void
136313 {
137314 if ( method_exists ( $ Controller , 'add ' ) )
138315 {
@@ -144,7 +321,14 @@ protected static function registerAdd( Application $App, string $Controller, str
144321 }
145322 }
146323
147- protected static function registerShow ( Application $ App , string $ Controller , string $ Route )
324+ /**
325+ * @param Application $App
326+ * @param string $Controller
327+ * @param string $Route
328+ * @return void
329+ * @throws BadRequestMethod
330+ */
331+ protected static function registerShow ( Application $ App , string $ Controller , string $ Route ): void
148332 {
149333 if ( method_exists ( $ Controller , 'show ' ) )
150334 {
@@ -156,7 +340,14 @@ protected static function registerShow( Application $App, string $Controller, st
156340 }
157341 }
158342
159- protected static function registerCreate ( Application $ App , string $ Controller , string $ Route )
343+ /**
344+ * @param Application $App
345+ * @param string $Controller
346+ * @param string $Route
347+ * @return void
348+ * @throws BadRequestMethod
349+ */
350+ protected static function registerCreate ( Application $ App , string $ Controller , string $ Route ): void
160351 {
161352 if ( method_exists ( $ Controller , 'create ' ) )
162353 {
@@ -168,7 +359,14 @@ protected static function registerCreate( Application $App, string $Controller,
168359 }
169360 }
170361
171- protected static function registerEdit ( Application $ App , string $ Controller , string $ Route )
362+ /**
363+ * @param Application $App
364+ * @param string $Controller
365+ * @param string $Route
366+ * @return void
367+ * @throws BadRequestMethod
368+ */
369+ protected static function registerEdit ( Application $ App , string $ Controller , string $ Route ): void
172370 {
173371 if ( method_exists ( $ Controller , 'edit ' ) )
174372 {
@@ -180,7 +378,14 @@ protected static function registerEdit( Application $App, string $Controller, st
180378 }
181379 }
182380
183- protected static function registerUpdate ( Application $ App , string $ Controller , string $ Route )
381+ /**
382+ * @param Application $App
383+ * @param string $Controller
384+ * @param string $Route
385+ * @return void
386+ * @throws BadRequestMethod
387+ */
388+ protected static function registerUpdate ( Application $ App , string $ Controller , string $ Route ): void
184389 {
185390 if ( method_exists ( $ Controller , 'update ' ) )
186391 {
@@ -192,7 +397,14 @@ protected static function registerUpdate( Application $App, string $Controller,
192397 }
193398 }
194399
195- protected static function registerDelete ( Application $ App , string $ Controller , string $ Route )
400+ /**
401+ * @param Application $App
402+ * @param string $Controller
403+ * @param string $Route
404+ * @return void
405+ * @throws BadRequestMethod
406+ */
407+ protected static function registerDelete ( Application $ App , string $ Controller , string $ Route ): void
196408 {
197409 if ( method_exists ( $ Controller , 'delete ' ) )
198410 {
@@ -203,5 +415,4 @@ protected static function registerDelete( Application $App, string $Controller,
203415 );
204416 }
205417 }
206-
207418}
0 commit comments