getManifest()->getModules(); foreach ($modules as $module) { if (strpos($callingfile, realpath($module->getPath())) === 0) { return $module; } } return null; } /** * 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 * @param $level - 1 (default) will return immediate caller, 2 will return caller's caller, etc. * @return string - the name of the method */ protected static function get_called_method_from_trace($backtrace, $level = 1) { $level = (int)$level; if (!$level) { $level = 1; } $called = $backtrace[$level]; if (isset($called['class'])) { return $called['class'] . $called['type'] . $called['function']; } else { return $called['function']; } } /** * Determine if deprecation notices should be displayed * * @return bool */ public static function get_enabled() { // Deprecation is only available on dev if (!Director::isDev()) { return false; } if (isset(self::$enabled)) { return self::$enabled; } return getenv('SS_DEPRECATION_ENABLED') ?: true; } /** * Toggle on or off deprecation notices. Will be ignored in live. * * @param bool $enabled */ public static function set_enabled($enabled) { self::$enabled = $enabled; } /** * 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 * * @param string $atVersion The version at which this notice should start being raised * @param string $string The notice to raise * @param int $scope Notice relates to the method or class context its called in. */ public static function notice($atVersion, $string = '', $scope = Deprecation::SCOPE_METHOD) { if (!static::get_enabled()) { return; } $checkVersion = self::$version; // Getting a backtrace is slow, so we only do it if we need it $backtrace = null; // If you pass #.#, assume #.#.0 if (preg_match('/^[0-9]+\.[0-9]+$/', $atVersion)) { $atVersion .= '.0'; } if (preg_match('/^[0-9]+\.[0-9]+$/', $checkVersion)) { $checkVersion .= '.0'; } if (self::$module_version_overrides) { $module = self::get_calling_module_from_trace($backtrace = debug_backtrace(0)); if ($module) { if (($name = $module->getComposerName()) && isset(self::$module_version_overrides[$name]) ) { $checkVersion = self::$module_version_overrides[$name]; } elseif (($name = $module->getShortName()) && isset(self::$module_version_overrides[$name]) ) { $checkVersion = self::$module_version_overrides[$name]; } } } // Check the version against the notice version if ($checkVersion && version_compare($checkVersion, $atVersion, '>=')) { // Get the calling scope if ($scope == Deprecation::SCOPE_METHOD) { if (!$backtrace) { $backtrace = debug_backtrace(0); } $caller = self::get_called_method_from_trace($backtrace); } elseif ($scope == Deprecation::SCOPE_CLASS) { if (!$backtrace) { $backtrace = debug_backtrace(0); } $caller = isset($backtrace[1]['class']) ? $backtrace[1]['class'] : '(unknown)'; } else { $caller = false; } // Get the level to raise the notice as $level = self::$notice_level; if (!$level) { $level = E_USER_DEPRECATED; } // Then raise the notice if (substr($string, -1) != '.') { $string .= "."; } $string .= " Called from " . self::get_called_method_from_trace($backtrace, 2) . '.'; if ($caller) { user_error($caller.' is deprecated.'.($string ? ' '.$string : ''), $level); } else { user_error($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 {@see Deprecation::restore_settings()} */ public static function dump_settings() { return array( 'level' => self::$notice_level, 'version' => self::$version, 'moduleVersions' => self::$module_version_overrides, 'enabled' => self::$enabled, ); } /** * Method for when testing. Restore all the current version settings from a variable * * @param $settings array An array as returned by {@see Deprecation::dump_settings()} */ public static function restore_settings($settings) { self::$notice_level = $settings['level']; self::$version = $settings['version']; self::$module_version_overrides = $settings['moduleVersions']; self::$enabled = $settings['enabled']; } }