Page MenuHomePhabricator

D12318.diff
No OneTemporary

D12318.diff

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
@@ -1262,7 +1262,6 @@
'PeopleCreateUsersCapability' => 'applications/people/capability/PeopleCreateUsersCapability.php',
'PeopleUserLogGarbageCollector' => 'applications/people/garbagecollector/PeopleUserLogGarbageCollector.php',
'Phabricator404Controller' => 'applications/base/controller/Phabricator404Controller.php',
- 'PhabricatorAPCSetupCheck' => 'applications/config/check/PhabricatorAPCSetupCheck.php',
'PhabricatorAWSConfigOptions' => 'applications/config/option/PhabricatorAWSConfigOptions.php',
'PhabricatorAccessControlTestCase' => 'applications/base/controller/__tests__/PhabricatorAccessControlTestCase.php',
'PhabricatorAccessLog' => 'infrastructure/log/PhabricatorAccessLog.php',
@@ -1474,6 +1473,7 @@
'PhabricatorCacheManagementWorkflow' => 'applications/cache/management/PhabricatorCacheManagementWorkflow.php',
'PhabricatorCacheMarkupGarbageCollector' => 'applications/cache/garbagecollector/PhabricatorCacheMarkupGarbageCollector.php',
'PhabricatorCacheSchemaSpec' => 'applications/cache/storage/PhabricatorCacheSchemaSpec.php',
+ 'PhabricatorCacheSetupCheck' => 'applications/config/check/PhabricatorCacheSetupCheck.php',
'PhabricatorCacheSpec' => 'applications/cache/spec/PhabricatorCacheSpec.php',
'PhabricatorCacheTTLGarbageCollector' => 'applications/cache/garbagecollector/PhabricatorCacheTTLGarbageCollector.php',
'PhabricatorCaches' => 'applications/cache/PhabricatorCaches.php',
@@ -4544,7 +4544,6 @@
'PeopleCreateUsersCapability' => 'PhabricatorPolicyCapability',
'PeopleUserLogGarbageCollector' => 'PhabricatorGarbageCollector',
'Phabricator404Controller' => 'PhabricatorController',
- 'PhabricatorAPCSetupCheck' => 'PhabricatorSetupCheck',
'PhabricatorAWSConfigOptions' => 'PhabricatorApplicationConfigOptions',
'PhabricatorAccessControlTestCase' => 'PhabricatorTestCase',
'PhabricatorAccessLogConfigOptions' => 'PhabricatorApplicationConfigOptions',
@@ -4768,6 +4767,7 @@
'PhabricatorCacheManagementWorkflow' => 'PhabricatorManagementWorkflow',
'PhabricatorCacheMarkupGarbageCollector' => 'PhabricatorGarbageCollector',
'PhabricatorCacheSchemaSpec' => 'PhabricatorConfigSchemaSpec',
+ 'PhabricatorCacheSetupCheck' => 'PhabricatorSetupCheck',
'PhabricatorCacheSpec' => 'Phobject',
'PhabricatorCacheTTLGarbageCollector' => 'PhabricatorGarbageCollector',
'PhabricatorCalendarApplication' => 'PhabricatorApplication',
diff --git a/src/applications/cache/spec/PhabricatorCacheSpec.php b/src/applications/cache/spec/PhabricatorCacheSpec.php
--- a/src/applications/cache/spec/PhabricatorCacheSpec.php
+++ b/src/applications/cache/spec/PhabricatorCacheSpec.php
@@ -38,14 +38,10 @@
return $this->version;
}
- protected function newIssue($title, $body, $option = null) {
- $issue = array(
- 'title' => $title,
- 'body' => $body,
- 'option' => $option,
- );
-
- $this->issues[] = $issue;
+ protected function newIssue($key) {
+ $issue = id(new PhabricatorSetupIssue())
+ ->setIssueKey($key);
+ $this->issues[$key] = $issue;
return $issue;
}
@@ -81,6 +77,35 @@
return $this->entryCount;
}
+ protected function raiseInstallAPCIssue() {
+ $message = pht(
+ "Installing the PHP extension 'APC' (Alternative PHP Cache) will ".
+ "dramatically improve performance. Note that APC versions 3.1.14 and ".
+ "3.1.15 are broken; 3.1.13 is recommended instead.");
+
+ return $this
+ ->newIssue('extension.apc')
+ ->setShortName(pht('APC'))
+ ->setName(pht("PHP Extension 'APC' Not Installed"))
+ ->setMessage($message)
+ ->addPHPExtension('apc');
+ }
+ protected function raiseEnableAPCIssue() {
+ $summary = pht('Enabling APC/APCu will improve performance.');
+ $message = pht(
+ 'The APC or APCu PHP extensions are installed, but not enabled in your '.
+ 'PHP configuration. Enabling these extensions will improve Phabricator '.
+ 'performance. Edit the "apc.enabled" setting to enable these '.
+ 'extensions.');
+
+ return $this
+ ->newIssue('extension.apc.enabled')
+ ->setShortName(pht('APC/APCu Disabled'))
+ ->setName(pht('APC/APCu Extensions Not Enabled'))
+ ->setSummary($summary)
+ ->setMessage($message)
+ ->addPHPConfig('apc.enabled');
+ }
}
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
@@ -15,81 +15,70 @@
public static function getActiveCacheSpec() {
$spec = new PhabricatorDataCacheSpec();
+
// NOTE: If APCu is installed, it reports that APC is installed.
if (extension_loaded('apc') && !extension_loaded('apcu')) {
- return self::getAPCSpec($spec);
+ $spec->initAPCSpec();
} else if (extension_loaded('apcu')) {
- return self::getAPCuSpec($spec);
+ $spec->initAPCuSpec();
} else {
- return self::getNoneSpec($spec);
+ $spec->initNoneSpec();
}
+
+ return $spec;
}
- private static function getAPCSpec(PhabricatorDataCacheSpec $spec) {
- $spec
+ private function initAPCSpec() {
+ $this
->setName(pht('APC User Cache'))
->setVersion(phpversion('apc'));
if (ini_get('apc.enabled')) {
- $spec->setIsEnabled(true);
- self::getAPCCommonSpec($spec);
+ $this->setIsEnabled(true);
+ $this->initAPCCommonSpec();
} else {
- $spec->setIsEnabled(false);
- $spec->newIssue(
- pht('Enable APC'),
- pht(
- 'The "APC" extension is currently disabled. Set "apc.enabled" to '.
- 'true to provide caching.'),
- 'apc.enabled');
+ $this->setIsEnabled(false);
+ $this->raiseEnableAPCIssue();
}
-
- return $spec;
}
- private static function getAPCuSpec(PhabricatorDataCacheSpec $spec) {
- $spec
+ private function initAPCuSpec() {
+ $this
->setName(pht('APCu'))
->setVersion(phpversion('apcu'));
if (ini_get('apc.enabled')) {
- $spec->setIsEnabled(true);
- self::getAPCCommonSpec($spec);
+ $this->setIsEnabled(true);
+ $this->getAPCCommonSpec();
} else {
- $spec->setIsEnabled(false);
- $spec->newissue(
- pht('Enable APCu'),
- pht(
- 'The "APCu" extension is currently disabled. Set '.
- '"apc.enabled" to true to provide caching.'),
- 'apc.enabled');
+ $this->setIsEnabled(false);
+ $this->raiseEnableAPCIssue();
}
-
- return $spec;
}
- private static function getNoneSpec(PhabricatorDataCacheSpec $spec) {
+ private function getNoneSpec() {
if (version_compare(phpversion(), '5.5', '>=')) {
- $spec->newIssue(
- pht('Install APCu'),
- pht(
- 'Install the "APCu" PHP extension to provide data caching.'));
+ $message = pht(
+ 'Installing the "APCu" PHP extension will improve performance.');
+
+ $this
+ ->newIssue('extension.apcu')
+ ->setShortName(pht('APCu'))
+ ->setName(pht('PHP Extension "APCu" Not Installed'))
+ ->setMessage($message)
+ ->addPHPExtension('apcu');
} else {
- $spec->newIssue(
- pht('Install APC'),
- pht(
- 'Install the "APC" PHP extension to provide data caching.'));
+ $this->raiseInstallAPCIssue();
}
-
- return $spec;
}
- private static function getAPCCommonSpec(PhabricatorDataCacheSpec $spec) {
+ private function getAPCCommonSpec() {
$mem = apc_sma_info();
- $spec->setTotalMemory($mem['num_seg'] * $mem['seg_size']);
+ $this->setTotalMemory($mem['num_seg'] * $mem['seg_size']);
$info = apc_cache_info('user');
- $spec->setUsedMemory($info['mem_size']);
- $spec->setEntryCount(count($info['cache_list']));
+ $this->setUsedMemory($info['mem_size']);
+ $this->setEntryCount(count($info['cache_list']));
$cache = $info['cache_list'];
$state = array();
@@ -107,7 +96,7 @@
$state[$key]['count']++;
}
- $spec->setCacheSummary($state);
+ $this->setCacheSummary($state);
}
private static function getKeyPattern($key) {
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
@@ -4,49 +4,85 @@
public static function getActiveCacheSpec() {
$spec = new PhabricatorOpcodeCacheSpec();
+
// NOTE: If APCu is installed, it reports that APC is installed.
if (extension_loaded('apc') && !extension_loaded('apcu')) {
- return self::getAPCSpec($spec);
+ $spec->initAPCSpec();
} else if (extension_loaded('Zend OPcache')) {
- return self::getOpcacheSpec($spec);
+ $spec->initOpcacheSpec();
} else {
- return self::getNoneSpec($spec);
+ $spec->initNoneSpec();
}
+
+ return $spec;
}
- private static function getAPCSpec(PhabricatorOpcodeCacheSpec $spec) {
- $spec
+ private function initAPCSpec() {
+ $this
->setName(pht('APC'))
->setVersion(phpversion('apc'));
if (ini_get('apc.enabled')) {
- $spec->setIsEnabled(true);
+ $this->setIsEnabled(true);
$mem = apc_sma_info();
- $spec->setTotalMemory($mem['num_seg'] * $mem['seg_size']);
+ $this->setTotalMemory($mem['num_seg'] * $mem['seg_size']);
$info = apc_cache_info();
- $spec->setUsedMemory($info['mem_size']);
+ $this->setUsedMemory($info['mem_size']);
+
+ $is_dev = PhabricatorEnv::getEnvConfig('phabricator.developer-mode');
+ $is_stat_enabled = ini_get('apc.stat');
+ if ($is_stat_enabled && !$is_dev) {
+ $summary = pht(
+ '"apc.stat" is currently enabled, but should probably be disabled.');
+
+ $message = pht(
+ 'The "apc.stat" setting is currently enabled in your PHP '.
+ 'configuration. In production mode, "apc.stat" should be '.
+ 'disabled. This will improve performance slightly.');
+
+ $this
+ ->newIssue('extension.apc.stat-enabled')
+ ->setShortName(pht('"apc.stat" Enabled'))
+ ->setName(pht('"apc.stat" Enabled in Production'))
+ ->setSummary($summary)
+ ->setMessage($message)
+ ->addPHPConfig('apc.stat')
+ ->addPhabricatorConfig('phabricator.developer-mode');
+ } else if (!$is_stat_enabled && $is_dev) {
+ $summary = pht(
+ '"apc.stat" is currently disabled, but should probably be enabled.');
+
+ $message = pht(
+ 'The "apc.stat" setting is currently disabled in your PHP '.
+ 'configuration, but Phabricator is running in development mode. '.
+ 'This option should normally be enabled in development so you do '.
+ 'not need to restart your webserver after making changes to the '.
+ 'code.');
+
+ $this
+ ->newIssue('extension.apc.stat-disabled')
+ ->setShortName(pht('"apc.stat" Disabled'))
+ ->setName(pht('"apc.stat" Disabled in Development'))
+ ->setSummary($summary)
+ ->setMessage($message)
+ ->addPHPConfig('apc.stat')
+ ->addPhabricatorConfig('phabricator.developer-mode');
+ }
} else {
- $spec->setIsEnabled(false);
- $spec->newIssue(
- pht('Enable APC'),
- pht(
- 'The "APC" extension is currently disabled. Set "apc.enabled" to '.
- 'true to improve performance.'),
- 'apc.enabled');
+ $this->setIsEnabled(false);
+ $this->raiseEnableAPCIssue();
}
-
- return $spec;
}
- private static function getOpcacheSpec(PhabricatorOpcodeCacheSpec $spec) {
- $spec
+ private function initOpcacheSpec() {
+ $this
->setName(pht('Zend OPcache'))
->setVersion(phpversion('Zend OPcache'));
if (ini_get('opcache.enable')) {
- $spec->setIsEnabled(true);
+ $this->setIsEnabled(true);
$status = opcache_get_status();
$memory = $status['memory_usage'];
@@ -54,36 +90,86 @@
$mem_used = $memory['used_memory'];
$mem_free = $memory['free_memory'];
$mem_junk = $memory['wasted_memory'];
- $spec->setUsedMemory($mem_used + $mem_junk);
- $spec->setTotalMemory($mem_used + $mem_junk + $mem_free);
- $spec->setEntryCount($status['opcache_statistics']['num_cached_keys']);
+ $this->setUsedMemory($mem_used + $mem_junk);
+ $this->setTotalMemory($mem_used + $mem_junk + $mem_free);
+ $this->setEntryCount($status['opcache_statistics']['num_cached_keys']);
+
+ $is_dev = PhabricatorEnv::getEnvConfig('phabricator.developer-mode');
+
+ $validate = ini_get('opcache.validate_timestamps');
+ $freq = ini_get('opcache.revalidate_freq');
+ if ($is_dev && (!$validate || $freq)) {
+ $summary = pht(
+ 'OPcache is not configured properly for development.');
+
+ $message = pht(
+ 'In development, OPcache should be configured to always reload '.
+ 'code so the webserver does not need to be restarted after making '.
+ 'changes. To do this, enable "opcache.validate_timestamps" and '.
+ 'set "opcache.revalidate_freq" to 0.');
+
+ $this
+ ->newIssue('extension.opcache.devmode')
+ ->setShortName(pht('OPcache Config'))
+ ->setName(pht('OPCache Not Configured for Development'))
+ ->setSummary($summary)
+ ->setMessage($message)
+ ->addPHPConfig('opcache.validate_timestamps')
+ ->addPHPConfig('opcache.revalidate_freq')
+ ->addPhabricatorConfig('phabricator.developer-mode');
+ } else if (!$is_dev && $validate) {
+ $summary = pht(
+ 'OPcache is not configured ideally for production.');
+
+ $message = pht(
+ 'In production, OPcache should be configured to never '.
+ 'revalidate code. This will slightly improve performance. '.
+ 'To do this, disable "opcache.validate_timestamps" in your PHP '.
+ 'configuration.');
+
+ $this
+ ->newIssue('extension.opcache.production')
+ ->setShortName(pht('OPcache Config'))
+ ->setName(pht('OPcache Not Configured for Production'))
+ ->setSummary($summary)
+ ->setMessage($message)
+ ->addPHPConfig('opcache.validate_timestamps')
+ ->addPhabricatorConfig('phabricator.developer-mode');
+ }
} else {
- $spec->setIsEnabled(false);
- $spec->newissue(
- pht('Enable Zend OPcache'),
- pht(
- 'The "Zend OPcache" extension is currently disabled. Set '.
- '"opcache.enable" to true to improve performance.'),
- 'opcache.enable');
- }
+ $this->setIsEnabled(false);
- return $spec;
+ $summary = pht('Enabling OPcache will dramatically improve performance.');
+ $message = pht(
+ 'The PHP "Zend OPcache" extension is installed, but not enabled in '.
+ 'your PHP configuration. Enabling it will dramatically improve '.
+ 'Phabricator performance. Edit the "opcache.enable" setting to '.
+ 'enable the extension.');
+
+ $this->newIssue('extension.opcache.enable')
+ ->setShortName(pht('OPcache Disabled'))
+ ->setName(pht('Zend OPcache Not Enabled'))
+ ->setSummary($summary)
+ ->setMessage($message)
+ ->addPHPConfig('opcache.enable');
+ }
}
- private static function getNoneSpec(PhabricatorOpcodeCacheSpec $spec) {
+ private function initNoneSpec() {
if (version_compare(phpversion(), '5.5', '>=')) {
- $spec->newIssue(
- pht('Install OPcache'),
- pht(
- 'Install the "Zend OPcache" PHP extension to improve performance.'));
+ $message = pht(
+ 'Installing the "Zend OPcache" extension will dramatically improve '.
+ 'performance.');
+
+ $this
+ ->newIssue('extension.opcache')
+ ->setShortName(pht('OPcache'))
+ ->setName(pht('Zend OPcache Not Installed'))
+ ->setMessage($message)
+ ->addPHPExtension('Zend OPcache');
} else {
- $spec->newIssue(
- pht('Install APC'),
- pht(
- 'Install the "APC" PHP extension to improve performance.'));
+ $this->raiseInstallAPCIssue();
}
-
- return $spec;
}
}
diff --git a/src/applications/config/check/PhabricatorAPCSetupCheck.php b/src/applications/config/check/PhabricatorAPCSetupCheck.php
deleted file mode 100644
--- a/src/applications/config/check/PhabricatorAPCSetupCheck.php
+++ /dev/null
@@ -1,89 +0,0 @@
-<?php
-
-final class PhabricatorAPCSetupCheck extends PhabricatorSetupCheck {
-
- public function getDefaultGroup() {
- return self::GROUP_OTHER;
- }
-
- protected function executeChecks() {
- if (!extension_loaded('apc')) {
- $message = pht(
- "Installing the PHP extension 'APC' (Alternative PHP Cache) will ".
- "dramatically improve performance. Note that APC versions 3.1.14 and ".
- "3.1.15 are broken; 3.1.13 is recommended instead.");
-
- $this
- ->newIssue('extension.apc')
- ->setShortName(pht('APC'))
- ->setName(pht("PHP Extension 'APC' Not Installed"))
- ->setMessage($message)
- ->addPHPExtension('apc');
- return;
- }
-
- if (!ini_get('apc.enabled')) {
- $summary = pht('Enabling APC will dramatically improve performance.');
- $message = pht(
- "The PHP extension 'APC' is installed, but not enabled in your PHP ".
- "configuration. Enabling it will dramatically improve Phabricator ".
- "performance. Edit the 'apc.enabled' setting to enable the extension.");
-
- $this
- ->newIssue('extension.apc.enabled')
- ->setShortName(pht('APC Disabled'))
- ->setName(pht("PHP Extension 'APC' Not Enabled"))
- ->setSummary($summary)
- ->setMessage($message)
- ->addPHPConfig('apc.enabled');
- return;
- }
-
- $is_dev = PhabricatorEnv::getEnvConfig('phabricator.developer-mode');
- $is_apcu = extension_loaded('apcu');
- $is_stat_enabled = ini_get('apc.stat');
-
- $issue_key = null;
- if ($is_stat_enabled && !$is_dev && !$is_apcu) {
- $issue_key = 'extension.apc.stat-enabled';
- $short = pht("'apc.stat' Enabled");
- $long = pht("'apc.stat' Enabled in Production");
- $summary = pht(
- "'apc.stat' is currently enabled, but should probably be disabled.");
- $message = pht(
- "'apc.stat' is currently enabled in your PHP configuration. For most ".
- "Phabricator installs, 'apc.stat' should be disabled. This will ".
- "slightly improve performance (PHP will do fewer disk reads) and make ".
- "updates safer (PHP won't read in the middle of a 'git pull').\n\n".
- "(If you are developing for Phabricator, leave 'apc.stat' enabled but ".
- "enable 'phabricator.developer-mode'.)");
- } else if (!$is_stat_enabled && $is_dev && !$is_apcu) {
- $issue_key = 'extension.apc.stat-disabled';
- $short = pht("'apc.stat' Disabled");
- $long = pht("'apc.stat' Disabled in Development");
- $summary = pht(
- "'apc.stat' is currently disabled, but should probably be enabled ".
- "in development mode.");
- $message = pht(
- "'apc.stat' is disabled in your PHP configuration, but Phabricator is ".
- "set to developer mode. Normally, you should enable 'apc.stat' for ".
- "development installs so you don't need to restart your webserver ".
- "after making changes to the code.\n\n".
- "You can enable 'apc.stat', or disable 'phabricator.developer-mode', ".
- "or safely ignore this warning if you have some reasoning behind ".
- "your current configuration.");
- }
-
- if ($issue_key !== null) {
- $this
- ->newIssue($issue_key)
- ->setShortName($short)
- ->setName($long)
- ->setSummary($summary)
- ->setMessage($message)
- ->addPHPConfig('apc.stat')
- ->addPhabricatorConfig('phabricator.developer-mode');
- }
- }
-
-}
diff --git a/src/applications/config/check/PhabricatorCacheSetupCheck.php b/src/applications/config/check/PhabricatorCacheSetupCheck.php
new file mode 100644
--- /dev/null
+++ b/src/applications/config/check/PhabricatorCacheSetupCheck.php
@@ -0,0 +1,20 @@
+<?php
+
+final class PhabricatorCacheSetupCheck extends PhabricatorSetupCheck {
+
+ public function getDefaultGroup() {
+ return self::GROUP_OTHER;
+ }
+
+ protected function executeChecks() {
+ $code_cache = PhabricatorOpcodeCacheSpec::getActiveCacheSpec();
+ $data_cache = PhabricatorDataCacheSpec::getActiveCacheSpec();
+
+ $issues = $code_cache->getIssues() + $data_cache->getIssues();
+
+ foreach ($issues as $issue) {
+ $this->addIssue($issue);
+ }
+ }
+
+}
diff --git a/src/applications/config/check/PhabricatorSetupCheck.php b/src/applications/config/check/PhabricatorSetupCheck.php
--- a/src/applications/config/check/PhabricatorSetupCheck.php
+++ b/src/applications/config/check/PhabricatorSetupCheck.php
@@ -31,6 +31,11 @@
return $this->issues;
}
+ protected function addIssue(PhabricatorSetupIssue $issue) {
+ $this->issues[$issue->getIssueKey()] = $issue;
+ return $this;
+ }
+
public function getDefaultGroup() {
return null;
}
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
@@ -40,7 +40,6 @@
$this->renderCommonProperties($properties, $cache);
return id(new PHUIObjectBoxView())
- ->setFormErrors($this->renderIssues($cache->getIssues()))
->setHeaderText(pht('Opcode Cache'))
->addPropertyList($properties);
}
@@ -146,20 +145,6 @@
}
- private function renderIssues(array $issues) {
- $result = array();
- foreach ($issues as $issue) {
- $title = $issue['title'];
- $body = $issue['body'];
- $result[] = array(
- phutil_tag('strong', array(), $title.':'),
- ' ',
- $body,
- );
- }
- return $result;
- }
-
private function renderYes($info) {
return array(
id(new PHUIIconView())->setIconFont('fa-check', 'green'),
diff --git a/src/applications/config/option/PhabricatorCoreConfigOptions.php b/src/applications/config/option/PhabricatorCoreConfigOptions.php
--- a/src/applications/config/option/PhabricatorCoreConfigOptions.php
+++ b/src/applications/config/option/PhabricatorCoreConfigOptions.php
@@ -209,7 +209,7 @@
->setLocked(true)
->setDescription(
pht('Custom HTML to show on the main Phabricator dashboard.')),
- $this->newOption('phabricator.cache-namespace', 'string', null)
+ $this->newOption('phabricator.cache-namespace', 'string', 'phabricator')
->setLocked(true)
->setDescription(pht('Cache namespace.')),
$this->newOption('phabricator.allow-email-users', 'bool', false)

File Metadata

Mime Type
text/plain
Expires
Mon, Oct 28, 3:22 AM (3 w, 1 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6732569
Default Alt Text
D12318.diff (23 KB)

Event Timeline