CacheHelperTest.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650
  1. <?php
  2. /**
  3. * CacheHelperTest file
  4. *
  5. * PHP 5
  6. *
  7. * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
  8. * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
  9. *
  10. * Licensed under The MIT License
  11. * Redistributions of files must retain the above copyright notice
  12. *
  13. * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
  14. * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
  15. * @package Cake.Test.Case.View.Helper
  16. * @since CakePHP(tm) v 1.2.0.4206
  17. * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
  18. */
  19. App::uses('Controller', 'Controller');
  20. App::uses('Model', 'Model');
  21. App::uses('View', 'View');
  22. App::uses('CacheHelper', 'View/Helper');
  23. /**
  24. * CacheTestController class
  25. *
  26. * @package Cake.Test.Case.View.Helper
  27. */
  28. class CacheTestController extends Controller {
  29. /**
  30. * helpers property
  31. *
  32. * @var array
  33. */
  34. public $helpers = array('Html', 'Cache');
  35. /**
  36. * cache_parsing method
  37. *
  38. * @return void
  39. */
  40. public function cache_parsing() {
  41. $this->viewPath = 'Posts';
  42. $this->layout = 'cache_layout';
  43. $this->set('variable', 'variableValue');
  44. $this->set('superman', 'clark kent');
  45. $this->set('batman', 'bruce wayne');
  46. $this->set('spiderman', 'peter parker');
  47. }
  48. }
  49. /**
  50. * CacheHelperTest class
  51. *
  52. * @package Cake.Test.Case.View.Helper
  53. */
  54. class CacheHelperTest extends CakeTestCase {
  55. /**
  56. * Checks if TMP/views is writable, and skips the case if it is not.
  57. *
  58. * @return void
  59. */
  60. public function skip() {
  61. if (!is_writable(TMP . 'cache' . DS . 'views' . DS)) {
  62. $this->markTestSkipped('TMP/views is not writable %s');
  63. }
  64. }
  65. /**
  66. * setUp method
  67. *
  68. * @return void
  69. */
  70. public function setUp() {
  71. parent::setUp();
  72. $_GET = array();
  73. $request = new CakeRequest();
  74. $this->Controller = new CacheTestController($request);
  75. $View = new View($this->Controller);
  76. $this->Cache = new CacheHelper($View);
  77. Configure::write('Cache.check', true);
  78. Configure::write('Cache.disable', false);
  79. App::build(array(
  80. 'View' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'View' . DS)
  81. ), App::RESET);
  82. }
  83. /**
  84. * tearDown method
  85. *
  86. * @return void
  87. */
  88. public function tearDown() {
  89. clearCache();
  90. unset($this->Cache);
  91. parent::tearDown();
  92. }
  93. /**
  94. * test cache parsing with no cake:nocache tags in view file.
  95. *
  96. * @return void
  97. */
  98. public function testLayoutCacheParsingNoTagsInView() {
  99. $this->Controller->cache_parsing();
  100. $this->Controller->request->addParams(array(
  101. 'controller' => 'cache_test',
  102. 'action' => 'cache_parsing',
  103. 'pass' => array(),
  104. 'named' => array()
  105. ));
  106. $this->Controller->cacheAction = 21600;
  107. $this->Controller->request->here = '/cacheTest/cache_parsing';
  108. $this->Controller->request->action = 'cache_parsing';
  109. $View = new View($this->Controller);
  110. $result = $View->render('index');
  111. $this->assertNotRegExp('/cake:nocache/', $result);
  112. $this->assertNotRegExp('/php echo/', $result);
  113. $filename = CACHE . 'views' . DS . 'cachetest_cache_parsing.php';
  114. $this->assertTrue(file_exists($filename));
  115. $contents = file_get_contents($filename);
  116. $this->assertRegExp('/php echo \$variable/', $contents);
  117. $this->assertRegExp('/php echo microtime()/', $contents);
  118. $this->assertRegExp('/clark kent/', $result);
  119. unlink($filename);
  120. }
  121. /**
  122. * test cache parsing with non-latin characters in current route
  123. *
  124. * @return void
  125. */
  126. public function testCacheNonLatinCharactersInRoute() {
  127. $this->Controller->cache_parsing();
  128. $this->Controller->request->addParams(array(
  129. 'controller' => 'cache_test',
  130. 'action' => 'cache_parsing',
  131. 'pass' => array('風街ろまん'),
  132. 'named' => array()
  133. ));
  134. $this->Controller->cacheAction = 21600;
  135. $this->Controller->request->here = '/posts/view/風街ろまん';
  136. $this->Controller->action = 'view';
  137. $View = new View($this->Controller);
  138. $View->render('index');
  139. $filename = CACHE . 'views' . DS . 'posts_view_風街ろまん.php';
  140. $this->assertTrue(file_exists($filename));
  141. unlink($filename);
  142. }
  143. /**
  144. * Test cache parsing with cake:nocache tags in view file.
  145. *
  146. * @return void
  147. */
  148. public function testLayoutCacheParsingWithTagsInView() {
  149. $this->Controller->cache_parsing();
  150. $this->Controller->request->addParams(array(
  151. 'controller' => 'cache_test',
  152. 'action' => 'cache_parsing',
  153. 'pass' => array(),
  154. 'named' => array()
  155. ));
  156. $this->Controller->cacheAction = 21600;
  157. $this->Controller->request->here = '/cacheTest/cache_parsing';
  158. $this->Controller->action = 'cache_parsing';
  159. $View = new View($this->Controller);
  160. $result = $View->render('test_nocache_tags');
  161. $this->assertNotRegExp('/cake:nocache/', $result);
  162. $this->assertNotRegExp('/php echo/', $result);
  163. $filename = CACHE . 'views' . DS . 'cachetest_cache_parsing.php';
  164. $this->assertTrue(file_exists($filename));
  165. $contents = file_get_contents($filename);
  166. $this->assertRegExp('/if \(is_writable\(TMP\)\)\:/', $contents);
  167. $this->assertRegExp('/php echo \$variable/', $contents);
  168. $this->assertRegExp('/php echo microtime()/', $contents);
  169. $this->assertNotRegExp('/cake:nocache/', $contents);
  170. unlink($filename);
  171. }
  172. /**
  173. * test that multiple <!--nocache--> tags function with multiple nocache tags in the layout.
  174. *
  175. * @return void
  176. */
  177. public function testMultipleNoCacheTagsInViewfile() {
  178. $this->Controller->cache_parsing();
  179. $this->Controller->request->addParams(array(
  180. 'controller' => 'cache_test',
  181. 'action' => 'cache_parsing',
  182. 'pass' => array(),
  183. 'named' => array()
  184. ));
  185. $this->Controller->cacheAction = 21600;
  186. $this->Controller->request->here = '/cacheTest/cache_parsing';
  187. $this->Controller->action = 'cache_parsing';
  188. $View = new View($this->Controller);
  189. $result = $View->render('multiple_nocache');
  190. $this->assertNotRegExp('/cake:nocache/', $result);
  191. $this->assertNotRegExp('/php echo/', $result);
  192. $filename = CACHE . 'views' . DS . 'cachetest_cache_parsing.php';
  193. $this->assertTrue(file_exists($filename));
  194. $contents = file_get_contents($filename);
  195. $this->assertNotRegExp('/cake:nocache/', $contents);
  196. unlink($filename);
  197. }
  198. /**
  199. * testComplexNoCache method
  200. *
  201. * @return void
  202. */
  203. public function testComplexNoCache() {
  204. $this->Controller->cache_parsing();
  205. $this->Controller->request->addParams(array(
  206. 'controller' => 'cache_test',
  207. 'action' => 'cache_complex',
  208. 'pass' => array(),
  209. 'named' => array()
  210. ));
  211. $this->Controller->cacheAction = array('cache_complex' => 21600);
  212. $this->Controller->request->here = '/cacheTest/cache_complex';
  213. $this->Controller->action = 'cache_complex';
  214. $this->Controller->layout = 'multi_cache';
  215. $this->Controller->viewPath = 'Posts';
  216. $View = new View($this->Controller);
  217. $result = $View->render('sequencial_nocache');
  218. $this->assertNotRegExp('/cake:nocache/', $result);
  219. $this->assertNotRegExp('/php echo/', $result);
  220. $this->assertRegExp('/A\. Layout Before Content/', $result);
  221. $this->assertRegExp('/B\. In Plain Element/', $result);
  222. $this->assertRegExp('/C\. Layout After Test Element/', $result);
  223. $this->assertRegExp('/D\. In View File/', $result);
  224. $this->assertRegExp('/E\. Layout After Content/', $result);
  225. $this->assertRegExp('/F\. In Element With No Cache Tags/', $result);
  226. $this->assertRegExp('/G\. Layout After Content And After Element With No Cache Tags/', $result);
  227. $this->assertNotRegExp('/1\. layout before content/', $result);
  228. $this->assertNotRegExp('/2\. in plain element/', $result);
  229. $this->assertNotRegExp('/3\. layout after test element/', $result);
  230. $this->assertNotRegExp('/4\. in view file/', $result);
  231. $this->assertNotRegExp('/5\. layout after content/', $result);
  232. $this->assertNotRegExp('/6\. in element with no cache tags/', $result);
  233. $this->assertNotRegExp('/7\. layout after content and after element with no cache tags/', $result);
  234. $filename = CACHE . 'views' . DS . 'cachetest_cache_complex.php';
  235. $this->assertTrue(file_exists($filename));
  236. $contents = file_get_contents($filename);
  237. unlink($filename);
  238. $this->assertRegExp('/A\. Layout Before Content/', $contents);
  239. $this->assertNotRegExp('/B\. In Plain Element/', $contents);
  240. $this->assertRegExp('/C\. Layout After Test Element/', $contents);
  241. $this->assertRegExp('/D\. In View File/', $contents);
  242. $this->assertRegExp('/E\. Layout After Content/', $contents);
  243. $this->assertRegExp('/F\. In Element With No Cache Tags/', $contents);
  244. $this->assertRegExp('/G\. Layout After Content And After Element With No Cache Tags/', $contents);
  245. $this->assertRegExp('/1\. layout before content/', $contents);
  246. $this->assertNotRegExp('/2\. in plain element/', $contents);
  247. $this->assertRegExp('/3\. layout after test element/', $contents);
  248. $this->assertRegExp('/4\. in view file/', $contents);
  249. $this->assertRegExp('/5\. layout after content/', $contents);
  250. $this->assertRegExp('/6\. in element with no cache tags/', $contents);
  251. $this->assertRegExp('/7\. layout after content and after element with no cache tags/', $contents);
  252. }
  253. /**
  254. * test cache of view vars
  255. *
  256. * @return void
  257. */
  258. public function testCacheViewVars() {
  259. $this->Controller->cache_parsing();
  260. $this->Controller->request->addParams(array(
  261. 'controller' => 'cache_test',
  262. 'action' => 'cache_parsing',
  263. 'pass' => array(),
  264. 'named' => array()
  265. ));
  266. $this->Controller->request->here = '/cacheTest/cache_parsing';
  267. $this->Controller->cacheAction = 21600;
  268. $View = new View($this->Controller);
  269. $result = $View->render('index');
  270. $this->assertNotRegExp('/cake:nocache/', $result);
  271. $this->assertNotRegExp('/php echo/', $result);
  272. $filename = CACHE . 'views' . DS . 'cachetest_cache_parsing.php';
  273. $this->assertTrue(file_exists($filename));
  274. $contents = file_get_contents($filename);
  275. $this->assertRegExp('/\$this\-\>viewVars/', $contents);
  276. $this->assertRegExp('/extract\(\$this\-\>viewVars, EXTR_SKIP\);/', $contents);
  277. $this->assertRegExp('/php echo \$variable/', $contents);
  278. unlink($filename);
  279. }
  280. /**
  281. * Test that callback code is generated correctly.
  282. *
  283. * @return void
  284. */
  285. public function testCacheCallbacks() {
  286. $this->Controller->request->addParams(array(
  287. 'controller' => 'cache_test',
  288. 'action' => 'cache_parsing',
  289. 'pass' => array(),
  290. 'named' => array()
  291. ));
  292. $this->Controller->cacheAction = array(
  293. 'cache_parsing' => array(
  294. 'duration' => 21600,
  295. 'callbacks' => true
  296. )
  297. );
  298. $this->Controller->request->here = '/cacheTest/cache_parsing';
  299. $this->Controller->cache_parsing();
  300. $View = new View($this->Controller);
  301. $View->render('index');
  302. $filename = CACHE . 'views' . DS . 'cachetest_cache_parsing.php';
  303. $this->assertTrue(file_exists($filename));
  304. $contents = file_get_contents($filename);
  305. $this->assertRegExp('/\$controller->startupProcess\(\);/', $contents);
  306. unlink($filename);
  307. }
  308. /**
  309. * test cacheAction set to a boolean
  310. *
  311. * @return void
  312. */
  313. public function testCacheActionArray() {
  314. $this->Controller->request->addParams(array(
  315. 'controller' => 'cache_test',
  316. 'action' => 'cache_parsing',
  317. 'pass' => array(),
  318. 'named' => array()
  319. ));
  320. $this->Controller->request->here = '/cache_test/cache_parsing';
  321. $this->Controller->cacheAction = array(
  322. 'cache_parsing' => 21600
  323. );
  324. $this->Controller->cache_parsing();
  325. $View = new View($this->Controller);
  326. $result = $View->render('index');
  327. $this->assertNotRegExp('/cake:nocache/', $result);
  328. $this->assertNotRegExp('/php echo/', $result);
  329. $filename = CACHE . 'views' . DS . 'cache_test_cache_parsing.php';
  330. $this->assertTrue(file_exists($filename));
  331. unlink($filename);
  332. }
  333. /**
  334. * Test that cacheAction works with camelcased controller names.
  335. *
  336. * @return void
  337. */
  338. public function testCacheActionArrayCamelCase() {
  339. $this->Controller->request->addParams(array(
  340. 'controller' => 'cache_test',
  341. 'action' => 'cache_parsing',
  342. 'pass' => array(),
  343. 'named' => array()
  344. ));
  345. $this->Controller->cacheAction = array(
  346. 'cache_parsing' => 21600
  347. );
  348. $this->Controller->request->here = '/cacheTest/cache_parsing';
  349. $this->Controller->cache_parsing();
  350. $View = new View($this->Controller);
  351. $result = $View->render('index');
  352. $this->assertNotRegExp('/cake:nocache/', $result);
  353. $this->assertNotRegExp('/php echo/', $result);
  354. $filename = CACHE . 'views' . DS . 'cachetest_cache_parsing.php';
  355. $this->assertTrue(file_exists($filename));
  356. unlink($filename);
  357. }
  358. /**
  359. * test with named and pass args.
  360. *
  361. * @return void
  362. */
  363. public function testCacheWithNamedAndPassedArgs() {
  364. Router::reload();
  365. $this->Controller->cache_parsing();
  366. $this->Controller->request->addParams(array(
  367. 'controller' => 'cache_test',
  368. 'action' => 'cache_parsing',
  369. 'pass' => array(1, 2),
  370. 'named' => array(
  371. 'name' => 'mark',
  372. 'ice' => 'cream'
  373. )
  374. ));
  375. $this->Controller->cacheAction = array(
  376. 'cache_parsing' => 21600
  377. );
  378. $this->Controller->request->here = '/cache_test/cache_parsing/1/2/name:mark/ice:cream';
  379. $View = new View($this->Controller);
  380. $result = $View->render('index');
  381. $this->assertNotRegExp('/cake:nocache/', $result);
  382. $this->assertNotRegExp('/php echo/', $result);
  383. $filename = CACHE . 'views' . DS . 'cache_test_cache_parsing_1_2_name_mark_ice_cream.php';
  384. $this->assertTrue(file_exists($filename));
  385. unlink($filename);
  386. }
  387. /**
  388. * Test that query string parameters are included in the cache filename.
  389. *
  390. * @return void
  391. */
  392. public function testCacheWithQueryStringParams() {
  393. Router::reload();
  394. $this->Controller->cache_parsing();
  395. $this->Controller->request->addParams(array(
  396. 'controller' => 'cache_test',
  397. 'action' => 'cache_parsing',
  398. 'pass' => array(),
  399. 'named' => array()
  400. ));
  401. $this->Controller->request->query = array('q' => 'cakephp');
  402. $this->Controller->cacheAction = array(
  403. 'cache_parsing' => 21600
  404. );
  405. $this->Controller->request->here = '/cache_test/cache_parsing';
  406. $View = new View($this->Controller);
  407. $result = $View->render('index');
  408. $this->assertNotRegExp('/cake:nocache/', $result);
  409. $this->assertNotRegExp('/php echo/', $result);
  410. $filename = CACHE . 'views' . DS . 'cache_test_cache_parsing_q_cakephp.php';
  411. $this->assertTrue(file_exists($filename), 'Missing cache file ' . $filename);
  412. unlink($filename);
  413. }
  414. /**
  415. * test that custom routes are respected when generating cache files.
  416. *
  417. * @return void
  418. */
  419. public function testCacheWithCustomRoutes() {
  420. Router::reload();
  421. Router::connect('/:lang/:controller/:action/*', array(), array('lang' => '[a-z]{3}'));
  422. $this->Controller->cache_parsing();
  423. $this->Controller->request->addParams(array(
  424. 'lang' => 'en',
  425. 'controller' => 'cache_test',
  426. 'action' => 'cache_parsing',
  427. 'pass' => array(),
  428. 'named' => array()
  429. ));
  430. $this->Controller->cacheAction = array(
  431. 'cache_parsing' => 21600
  432. );
  433. $this->Controller->request->here = '/en/cache_test/cache_parsing';
  434. $this->Controller->action = 'cache_parsing';
  435. $View = new View($this->Controller);
  436. $result = $View->render('index');
  437. $this->assertNotRegExp('/cake:nocache/', $result);
  438. $this->assertNotRegExp('/php echo/', $result);
  439. $filename = CACHE . 'views' . DS . 'en_cache_test_cache_parsing.php';
  440. $this->assertTrue(file_exists($filename));
  441. unlink($filename);
  442. }
  443. /**
  444. * test ControllerName contains AppName
  445. *
  446. * This test verifies view cache is created correctly when the app name is contained in part of the controller name.
  447. * (webapp Name) base name is 'cache' controller is 'cacheTest' action is 'cache_name'
  448. * apps url would look something like http://localhost/cache/cacheTest/cache_name
  449. *
  450. * @return void
  451. */
  452. public function testCacheBaseNameControllerName() {
  453. $this->Controller->cache_parsing();
  454. $this->Controller->cacheAction = array(
  455. 'cache_name' => 21600
  456. );
  457. $this->Controller->params = array(
  458. 'controller' => 'cacheTest',
  459. 'action' => 'cache_name',
  460. 'pass' => array(),
  461. 'named' => array()
  462. );
  463. $this->Controller->here = '/cache/cacheTest/cache_name';
  464. $this->Controller->action = 'cache_name';
  465. $this->Controller->base = '/cache';
  466. $View = new View($this->Controller);
  467. $result = $View->render('index');
  468. $this->assertNotRegExp('/cake:nocache/', $result);
  469. $this->assertNotRegExp('/php echo/', $result);
  470. $filename = CACHE . 'views' . DS . 'cache_cachetest_cache_name.php';
  471. $this->assertTrue(file_exists($filename));
  472. unlink($filename);
  473. }
  474. /**
  475. * test that afterRender checks the conditions correctly.
  476. *
  477. * @return void
  478. */
  479. public function testAfterRenderConditions() {
  480. Configure::write('Cache.check', true);
  481. $View = new View($this->Controller);
  482. $View->cacheAction = '+1 day';
  483. $View->output = 'test';
  484. $Cache = $this->getMock('CacheHelper', array('_parseContent'), array($View));
  485. $Cache->expects($this->once())
  486. ->method('_parseContent')
  487. ->with('posts/index', 'content')
  488. ->will($this->returnValue(''));
  489. $Cache->afterRenderFile('posts/index', 'content');
  490. Configure::write('Cache.check', false);
  491. $Cache->afterRender('posts/index');
  492. Configure::write('Cache.check', true);
  493. $View->cacheAction = false;
  494. $Cache->afterRender('posts/index');
  495. }
  496. /**
  497. * test that afterRender checks the conditions correctly.
  498. *
  499. * @return void
  500. */
  501. public function testAfterLayoutConditions() {
  502. Configure::write('Cache.check', true);
  503. $View = new View($this->Controller);
  504. $View->cacheAction = '+1 day';
  505. $View->output = 'test';
  506. $Cache = $this->getMock('CacheHelper', array('cache'), array($View));
  507. $Cache->expects($this->once())
  508. ->method('cache')
  509. ->with('posts/index', $View->output)
  510. ->will($this->returnValue(''));
  511. $Cache->afterLayout('posts/index');
  512. Configure::write('Cache.check', false);
  513. $Cache->afterLayout('posts/index');
  514. Configure::write('Cache.check', true);
  515. $View->cacheAction = false;
  516. $Cache->afterLayout('posts/index');
  517. }
  518. /**
  519. * testCacheEmptySections method
  520. *
  521. * This test must be uncommented/fixed in next release (1.2+)
  522. *
  523. * @return void
  524. */
  525. public function testCacheEmptySections() {
  526. $this->Controller->cache_parsing();
  527. $this->Controller->params = array(
  528. 'controller' => 'cacheTest',
  529. 'action' => 'cache_empty_sections',
  530. 'pass' => array(),
  531. 'named' => array()
  532. );
  533. $this->Controller->cacheAction = array('cache_empty_sections' => 21600);
  534. $this->Controller->here = '/cacheTest/cache_empty_sections';
  535. $this->Controller->action = 'cache_empty_sections';
  536. $this->Controller->layout = 'cache_empty_sections';
  537. $this->Controller->viewPath = 'Posts';
  538. $View = new View($this->Controller);
  539. $result = $View->render('cache_empty_sections');
  540. $this->assertNotRegExp('/nocache/', $result);
  541. $this->assertNotRegExp('/php echo/', $result);
  542. $this->assertRegExp(
  543. '@</title>\s*</head>\s*' .
  544. '<body>\s*' .
  545. 'View Content\s*' .
  546. 'cached count is: 3\s*' .
  547. '</body>@', $result);
  548. $filename = CACHE . 'views' . DS . 'cachetest_cache_empty_sections.php';
  549. $this->assertTrue(file_exists($filename));
  550. $contents = file_get_contents($filename);
  551. $this->assertNotRegExp('/nocache/', $contents);
  552. $this->assertRegExp(
  553. '@<head>\s*<title>Posts</title>\s*' .
  554. '<\?php \$x \= 1; \?>\s*' .
  555. '</head>\s*' .
  556. '<body>\s*' .
  557. '<\?php \$x\+\+; \?>\s*' .
  558. '<\?php \$x\+\+; \?>\s*' .
  559. 'View Content\s*' .
  560. '<\?php \$y = 1; \?>\s*' .
  561. '<\?php echo \'cached count is: \' . \$x; \?>\s*' .
  562. '@', $contents);
  563. unlink($filename);
  564. }
  565. }