diff --git a/_config.php b/_config.php index 4032b93c4..8ce65c2e6 100644 --- a/_config.php +++ b/_config.php @@ -77,5 +77,7 @@ if (!is_dir($aggregatecachedir)) mkdir($aggregatecachedir); SS_Cache::add_backend('aggregatestore', 'File', array('cache_dir' => $aggregatecachedir)); SS_Cache::pick_backend('aggregatestore', 'aggregate', 1000); +Deprecation::notification_version('3.0.0-dev'); + // TODO Remove once new ManifestBuilder with submodule support is in place require_once('admin/_config.php'); \ No newline at end of file diff --git a/dev/Deprecation.php b/dev/Deprecation.php new file mode 100644 index 000000000..623b21a91 --- /dev/null +++ b/dev/Deprecation.php @@ -0,0 +1,161 @@ +getModules() as $name => $path) { + if (strpos($callingfile, $path) === 0) { + return $name; + } + } + } + + /** + * Given a backtrace, get the method name from the immediate parent caller (the caller of #notice) + * + * @static + * @param $backtrace array - a backtrace as returned from debug_backtrace + * @return string - the name of the method + */ + protected static function get_called_method_from_trace($backtrace) { + $called = $backtrace[1]; + + if (isset($called['class'])) { + return $called['class'] . $called['type'] . $called['function']; + } + else { + return $called['function']; + } + } + + /** + * Raise a notice indicating the method is deprecated if the version passed as the second argument is greater + * than or equal to the check version set via ::notification_version + * + * @static + * @param $string - The notice to raise + * @param $atVersion - The version at which this notice should start being raised + * @return void + */ + public static function notice($atVersion, $string = '') { + if(!Director::isDev()) return; + + $checkVersion = self::$version; + // Getting a backtrace is slow, so we only do it if we need it + $backtrace = null; + + if(self::$module_version_overrides) { + $module = self::get_calling_module_from_trace($backtrace = debug_backtrace(0)); + if(isset(self::$module_version_overrides[$module])) $checkVersion = self::$module_version_overrides[$module]; + } + + // Check the version against the notice version + if ($checkVersion && version_compare($checkVersion, $atVersion, '>=')) { + // Get the calling method + if (!$backtrace) $backtrace = debug_backtrace(0); + $caller = self::get_called_method_from_trace($backtrace); + + // Get the level to raise the notice as + $level = self::$notice_level; + if (!$level) $level = defined(E_USER_DEPRECATED) ? E_USER_DEPRECATED : E_USER_NOTICE; + + // Then raise the notice + user_error($caller.' is deprecated.'.($string ? ' '.$string : ''), $level); + } + } + + /** + * Method for when testing. Dump all the current version settings to a variable for later passing to restore + * @return array - opaque array that should only be used to pass to ::restore_version_settings + */ + public static function dump_settings() { + return array( + 'level' => self::$notice_level, + 'version' => self::$version, + 'moduleVersions' => self::$module_version_overrides + ); + } + + /** + * Method for when testing. Restore all the current version settings from a variable + * @static + * @param $settings array - An array as returned by ::dump_version_settings + * @return void + */ + public static function restore_settings($settings) { + self::$notice_level = $settings['level']; + self::$version = $settings['version']; + self::$module_version_overrides = $settings['moduleVersions']; + } + +} \ No newline at end of file diff --git a/tests/dev/DeprecationTest.php b/tests/dev/DeprecationTest.php new file mode 100644 index 000000000..b36b05aa2 --- /dev/null +++ b/tests/dev/DeprecationTest.php @@ -0,0 +1,71 @@ +callThatOriginatesFromSapphire(); + } + + /** + * @expectedException PHPUnit_Framework_Error_Notice + */ + function testMatchingModuleNotifcationVersionAffectsNotice() { + Deprecation::notification_version('1.0.0'); + Deprecation::notification_version('3.0.0', 'sapphire'); + $this->callThatOriginatesFromSapphire(); + } + + protected function callThatOriginatesFromSapphire() { + $this->assertEquals(DeprecationTest_Deprecation::get_module(), 'sapphire'); + Deprecation::notice('2.0.0', 'Deprecation test passed'); + } + + function testMethodNameCalculation() { + $this->assertEquals(DeprecationTest_Deprecation::get_method(), 'DeprecationTest->testMethodNameCalculation'); + } + +}