diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -1842,6 +1842,7 @@ 'PhabricatorConfigOptionType' => 'applications/config/custom/PhabricatorConfigOptionType.php', 'PhabricatorConfigPHIDModule' => 'applications/config/module/PhabricatorConfigPHIDModule.php', 'PhabricatorConfigProxySource' => 'infrastructure/env/PhabricatorConfigProxySource.php', + 'PhabricatorConfigPurgeCacheController' => 'applications/config/controller/PhabricatorConfigPurgeCacheController.php', 'PhabricatorConfigRequestExceptionHandlerModule' => 'applications/config/module/PhabricatorConfigRequestExceptionHandlerModule.php', 'PhabricatorConfigResponse' => 'applications/config/response/PhabricatorConfigResponse.php', 'PhabricatorConfigSchemaQuery' => 'applications/config/schema/PhabricatorConfigSchemaQuery.php', @@ -5743,6 +5744,7 @@ 'PhabricatorConfigOptionType' => 'Phobject', 'PhabricatorConfigPHIDModule' => 'PhabricatorConfigModule', 'PhabricatorConfigProxySource' => 'PhabricatorConfigSource', + 'PhabricatorConfigPurgeCacheController' => 'PhabricatorController', 'PhabricatorConfigRequestExceptionHandlerModule' => 'PhabricatorConfigModule', 'PhabricatorConfigResponse' => 'AphrontStandaloneHTMLResponse', 'PhabricatorConfigSchemaQuery' => 'Phobject', diff --git a/src/applications/cache/management/PhabricatorCacheManagementPurgeWorkflow.php b/src/applications/cache/management/PhabricatorCacheManagementPurgeWorkflow.php --- a/src/applications/cache/management/PhabricatorCacheManagementPurgeWorkflow.php +++ b/src/applications/cache/management/PhabricatorCacheManagementPurgeWorkflow.php @@ -6,7 +6,8 @@ protected function didConstruct() { $this ->setName('purge') - ->setSynopsis(pht('Drop data from caches.')) + ->setSynopsis(pht('Drop data from caches. APC-based caches can be '. + 'purged from the web interface.')) ->setArguments( array( array( diff --git a/src/applications/cache/spec/PhabricatorDataCacheSpec.php b/src/applications/cache/spec/PhabricatorDataCacheSpec.php --- a/src/applications/cache/spec/PhabricatorDataCacheSpec.php +++ b/src/applications/cache/spec/PhabricatorDataCacheSpec.php @@ -119,4 +119,14 @@ return $key; } + public function isClearable() { + return $this->getName() && $this->getIsEnabled(); + } + + public function clear() { + if ($this->getName() === pht('APC User Cache') || + $this->getName() === pht('APCu')) { + apc_clear_cache(); + } + } } diff --git a/src/applications/cache/spec/PhabricatorOpcodeCacheSpec.php b/src/applications/cache/spec/PhabricatorOpcodeCacheSpec.php --- a/src/applications/cache/spec/PhabricatorOpcodeCacheSpec.php +++ b/src/applications/cache/spec/PhabricatorOpcodeCacheSpec.php @@ -200,4 +200,15 @@ } } + public function isClearable() { + return $this->getName() && $this->getIsEnabled(); + } + + public function clear() { + if ($this->getName() === pht('APC')) { + apc_clear_cache(); + } else if ($this->getName() === pht('Zend OPcache')) { + opcache_reset(); + } + } } diff --git a/src/applications/config/application/PhabricatorConfigApplication.php b/src/applications/config/application/PhabricatorConfigApplication.php --- a/src/applications/config/application/PhabricatorConfigApplication.php +++ b/src/applications/config/application/PhabricatorConfigApplication.php @@ -55,7 +55,10 @@ '' => 'PhabricatorConfigIssueListController', '(?P[^/]+)/' => 'PhabricatorConfigIssueViewController', ), - 'cache/' => 'PhabricatorConfigCacheController', + 'cache/' => array( + '' => 'PhabricatorConfigCacheController', + 'purge/' => 'PhabricatorConfigPurgeCacheController', + ), 'module/' => array( '(?P[^/]+)/' => 'PhabricatorConfigModuleController', ), diff --git a/src/applications/config/controller/PhabricatorConfigCacheController.php b/src/applications/config/controller/PhabricatorConfigCacheController.php --- a/src/applications/config/controller/PhabricatorConfigCacheController.php +++ b/src/applications/config/controller/PhabricatorConfigCacheController.php @@ -39,8 +39,22 @@ $this->renderCommonProperties($properties, $cache); + $purge_icon = id(new PHUIIconView()) + ->setIconFont('fa-exclamation-triangle'); + + $purge_button = id(new PHUIButtonView()) + ->setText(pht('Purge Caches')) + ->setHref('/config/cache/purge/') + ->setTag('a') + ->setWorkflow(true) + ->setIcon($purge_icon); + + $header = id(new PHUIHeaderView()) + ->setHeader(pht('Opcode Cache')) + ->addActionLink($purge_button); + return id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Opcode Cache')) + ->setHeader($header) ->addPropertyList($properties); } diff --git a/src/applications/config/controller/PhabricatorConfigPurgeCacheController.php b/src/applications/config/controller/PhabricatorConfigPurgeCacheController.php new file mode 100644 --- /dev/null +++ b/src/applications/config/controller/PhabricatorConfigPurgeCacheController.php @@ -0,0 +1,54 @@ +getViewer(); + + $code_cache = PhabricatorOpcodeCacheSpec::getActiveCacheSpec(); + $data_cache = PhabricatorDataCacheSpec::getActiveCacheSpec(); + + if (!$code_cache->isClearable() && !$data_cache->isClearable()) { + return $this->newDialog() + ->setTitle(pht('No Caches to Reset')) + ->appendParagraph( + pht('None of the caches on this page can be cleared.')) + ->addCancelButton('/config/cache/'); + } + + if ($request->isDialogFormPost()) { + $code_cache->clear(); + $data_cache->clear(); + + return id(new AphrontRedirectResponse())->setURI('/config/cache'); + } + + $caches = id(new PHUIPropertyListView()) + ->setUser($viewer); + + if ($code_cache->isClearable()) { + $caches->addProperty( + pht('Opcode'), + $code_cache->getName()); + } + + if ($data_cache->isClearable()) { + $caches->addProperty( + pht('Data'), + $data_cache->getName()); + } + + return $this->newDialog() + ->setTitle('Really Clear Cache?') + ->setShortTitle('Really Clear Cache') + ->appendParagraph(pht('The following caches will be cleared:')) + ->appendChild($caches) + ->addSubmitButton(pht('Clear')) + ->addCancelButton('/config/cache/'); + } +}