diff --git a/admin/code/LeftAndMainDecorator.php b/admin/code/LeftAndMainDecorator.php index b9857dd084b..59169bb9df3 100644 --- a/admin/code/LeftAndMainDecorator.php +++ b/admin/code/LeftAndMainDecorator.php @@ -7,7 +7,7 @@ abstract class LeftAndMainDecorator extends LeftAndMainExtension { public function __construct() { - Deprecation::notice('3.0', 'Use LeftAndMainExtension instead.'); + Deprecation::notice('3.0', 'Use LeftAndMainExtension instead.', Deprecation::SCOPE_CLASS); parent::__construct(); } diff --git a/control/Director.php b/control/Director.php index f3540abe1a3..bc39735036e 100644 --- a/control/Director.php +++ b/control/Director.php @@ -42,7 +42,7 @@ class Director implements TemplateGlobalProvider { */ static function addRules($priority, $rules) { if ($priority != 100) { - Deprecation::notice('3.0', 'Priority argument is now ignored - use the default of 100. You should really be setting routes via _config yaml fragments though.'); + Deprecation::notice('3.0', 'Priority argument is now ignored - use the default of 100. You should really be setting routes via _config yaml fragments though.', Deprecation::SCOPE_GLOBAL); } Config::inst()->update('Director', 'rules', $rules); diff --git a/core/Object.php b/core/Object.php index 08e3d165d00..b374237621d 100755 --- a/core/Object.php +++ b/core/Object.php @@ -332,7 +332,7 @@ public static function static_lookup($class, $name, $default = null) { * @return mixed */ public static function get_static($class, $name, $uncached = false) { - Deprecation::notice('3.1.0', 'get_static is deprecated, replaced by Config#get'); + Deprecation::notice('3.1.0', 'Replaced by Config#get'); return Config::inst()->get($class, $name, Config::FIRST_SET); } @@ -344,7 +344,7 @@ public static function get_static($class, $name, $uncached = false) { * @param mixed $value */ public static function set_static($class, $name, $value) { - Deprecation::notice('3.1.0', 'set_static is deprecated, replaced by Config#update'); + Deprecation::notice('3.1.0', 'Replaced by Config#update'); Config::inst()->update($class, $name, $value); } @@ -356,7 +356,7 @@ public static function set_static($class, $name, $value) { * @return mixed */ public static function uninherited_static($class, $name, $uncached = false) { - Deprecation::notice('3.1.0', 'uninherited_static is deprecated, replaced by Config#get'); + Deprecation::notice('3.1.0', 'Replaced by Config#get'); return Config::inst()->get($class, $name, Config::UNINHERITED); } @@ -373,7 +373,7 @@ public static function uninherited_static($class, $name, $uncached = false) { public static function combined_static($class, $name, $ceiling = false) { if ($ceiling) throw new Exception('Ceiling argument to combined_static is no longer supported'); - Deprecation::notice('3.1.0', 'combined_static is deprecated, replaced by Config#get'); + Deprecation::notice('3.1.0', 'Replaced by Config#get'); return Config::inst()->get($class, $name); } @@ -385,7 +385,7 @@ public static function combined_static($class, $name, $ceiling = false) { * @param bool $replace replace existing static vars */ public static function addStaticVars($class, $properties, $replace = false) { - Deprecation::notice('3.1.0', 'addStaticVars is deprecated, replaced by Config#update'); + Deprecation::notice('3.1.0', 'Replaced by Config#update'); foreach($properties as $prop => $value) self::add_static_var($class, $prop, $value, $replace); } @@ -406,7 +406,7 @@ public static function addStaticVars($class, $properties, $replace = false) { * @param bool $replace completely replace existing static values */ public static function add_static_var($class, $name, $value, $replace = false) { - Deprecation::notice('3.1.0', 'add_static_var is deprecated, replaced by Config#remove and Config#update'); + Deprecation::notice('3.1.0', 'Replaced by Config#remove and Config#update'); if ($replace) Config::inst()->remove($class, $name); Config::inst()->update($class, $name, $value); diff --git a/dev/Deprecation.php b/dev/Deprecation.php index 071e311462b..8e9a9399fd0 100644 --- a/dev/Deprecation.php +++ b/dev/Deprecation.php @@ -32,6 +32,10 @@ */ class Deprecation { + const SCOPE_METHOD = 1; + const SCOPE_CLASS = 2; + const SCOPE_GLOBAL = 4; + /** * * @var string @@ -119,9 +123,10 @@ protected static function get_called_method_from_trace($backtrace, $level = 1) { * @static * @param $string - The notice to raise * @param $atVersion - The version at which this notice should start being raised + * @param Boolean $scope - Notice relates to the method or class context its called in. * @return void */ - public static function notice($atVersion, $string = '') { + public static function notice($atVersion, $string = '', $scope = Deprecation::SCOPE_METHOD) { // Never raise deprecation notices in a live environment if(Director::isLive()) return; @@ -139,9 +144,16 @@ public static function notice($atVersion, $string = '') { // 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 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; @@ -152,7 +164,12 @@ public static function notice($atVersion, $string = '') { $string .= " Called from " . self::get_called_method_from_trace($backtrace, 2) . '.'; - user_error($caller.' is deprecated.'.($string ? ' '.$string : ''), $level); + if($caller) { + user_error($caller.' is deprecated.'.($string ? ' '.$string : ''), $level); + } else { + user_error($string, $level); + } + } } diff --git a/filesystem/Folder.php b/filesystem/Folder.php index dc8ed54722f..940981acd0e 100644 --- a/filesystem/Folder.php +++ b/filesystem/Folder.php @@ -41,7 +41,7 @@ public function populateDefaults() { * @deprecated in favor of the correct name find_or_make */ public static function findOrMake($folderPath) { - Deprecation::notice('3.0', "Folder::findOrMake() is deprecated in favor of Folder::find_or_make()"); + Deprecation::notice('3.0', "Use Folder::find_or_make() instead."); return self::find_or_make($folderPath); } diff --git a/forms/DropdownField.php b/forms/DropdownField.php index 09a111e5561..ec62092fa23 100644 --- a/forms/DropdownField.php +++ b/forms/DropdownField.php @@ -118,10 +118,10 @@ function __construct($name, $title = null, $source = array(), $value = '', $form $this->setSource($source); if($emptyString === true) { - Deprecation::notice('3.1', 'Please use setHasEmptyDefault(true) instead of passing a boolean true $emptyString argument'); + Deprecation::notice('3.1', 'Please use setHasEmptyDefault(true) instead of passing a boolean true $emptyString argument', Deprecation::SCOPE_GLOBAL); } if(is_string($emptyString)) { - Deprecation::notice('3.1', 'Please use setEmptyString() instead of passing a string $emptyString argument.'); + Deprecation::notice('3.1', 'Please use setEmptyString() instead of passing a string $emptyString argument.', Deprecation::SCOPE_GLOBAL); } if($emptyString) $this->setHasEmptyDefault(true); diff --git a/forms/FieldList.php b/forms/FieldList.php index 094d9a94578..9ea578ecd78 100644 --- a/forms/FieldList.php +++ b/forms/FieldList.php @@ -605,11 +605,14 @@ protected function rewriteTabPath($name) { foreach($this->getTabPathRewrites() as $regex => $replace) { if(preg_match($regex, $name)) { $newName = preg_replace($regex, $replace, $name); - Deprecation::notice('3.0.0', sprintf( - 'Using outdated tab path "%s", please use the new location "%s" instead', - $name, - $newName - )); + Deprecation::notice('3.0.0', + sprintf( + 'Using outdated tab path "%s", please use the new location "%s" instead', + $name, + $newName + ), + Deprecation::SCOPE_GLOBAL + ); return $newName; } } diff --git a/forms/FileField.php b/forms/FileField.php index e384ba3429b..21cf82dcc43 100644 --- a/forms/FileField.php +++ b/forms/FileField.php @@ -102,7 +102,13 @@ class FileField extends FormField { * @param int $value The value of the field. */ function __construct($name, $title = null, $value = null) { - if(count(func_get_args()) > 3) Deprecation::notice('3.0', 'Use setRightTitle() and setFolderName() instead of constructor arguments'); + if(count(func_get_args()) > 3) { + Deprecation::notice( + '3.0', + 'Use setRightTitle() and setFolderName() instead of constructor arguments', + Deprecation::SCOPE_GLOBAL + ); + } $this->upload = new Upload(); diff --git a/forms/HasManyComplexTableField.php b/forms/HasManyComplexTableField.php index d6b25b56d0e..fdd56940616 100644 --- a/forms/HasManyComplexTableField.php +++ b/forms/HasManyComplexTableField.php @@ -51,7 +51,7 @@ class HasManyComplexTableField extends ComplexTableField { function __construct($controller, $name, $sourceClass, $fieldList = null, $detailFormFields = null, $sourceFilter = "", $sourceSort = "", $sourceJoin = "") { parent::__construct($controller, $name, $sourceClass, $fieldList, $detailFormFields, $sourceFilter, $sourceSort, $sourceJoin); - Deprecation::notice('3.0', 'Use GridField with GridFieldConfig_RelationEditor'); + Deprecation::notice('3.0', 'Use GridField with GridFieldConfig_RelationEditor', Deprecation::SCOPE_CLASS); $this->Markable = true; diff --git a/forms/HtmlEditorField.php b/forms/HtmlEditorField.php index 7a71fd0a5b8..d3017613947 100644 --- a/forms/HtmlEditorField.php +++ b/forms/HtmlEditorField.php @@ -46,7 +46,7 @@ public static function include_js() { * @see TextareaField::__construct() */ public function __construct($name, $title = null, $value = '') { - if(count(func_get_args()) > 3) Deprecation::notice('3.0', 'Use setRows() and setCols() instead of constructor arguments'); + if(count(func_get_args()) > 3) Deprecation::notice('3.0', 'Use setRows() and setCols() instead of constructor arguments', Deprecation::SCOPE_GLOBAL); parent::__construct($name, $title, $value); diff --git a/forms/ImageField.php b/forms/ImageField.php index eabdd6e8e68..c49871d422b 100644 --- a/forms/ImageField.php +++ b/forms/ImageField.php @@ -45,7 +45,7 @@ public function FileTypeName() { * @return Form */ public function EditFileForm() { - Deprecation::notice('3.0', 'Use UploadField'); + Deprecation::notice('3.0', 'Use UploadField', Deprecation::SCOPE_CLASS); $filter = create_function('$item', 'return (in_array("Folder", ClassInfo::ancestry($item->ClassName)) || in_array("Image", ClassInfo::ancestry($item->ClassName)));'); diff --git a/forms/ImageFormAction.php b/forms/ImageFormAction.php index d7fa7244586..9932fcff1ea 100644 --- a/forms/ImageFormAction.php +++ b/forms/ImageFormAction.php @@ -18,7 +18,7 @@ class ImageFormAction extends FormAction { * @param form The parent form, auto-set when the field is placed inside a form */ function __construct($action, $title = "", $image = "", $hoverImage = null, $className = null, $form = null) { - Deprecation::notice('3.0', "Use FormAction with setAttribute('src', 'myimage.png') and custom JavaScript to achieve hover effect"); + Deprecation::notice('3.0', "Use FormAction with setAttribute('src', 'myimage.png') and custom JavaScript to achieve hover effect", Deprecation::SCOPE_CLASS); $this->image = $image; $this->hoverImage = $hoverImage; diff --git a/forms/ManyManyComplexTableField.php b/forms/ManyManyComplexTableField.php index d14e9b73153..9592a933eb9 100644 --- a/forms/ManyManyComplexTableField.php +++ b/forms/ManyManyComplexTableField.php @@ -43,7 +43,7 @@ class ManyManyComplexTableField extends HasManyComplexTableField { function __construct($controller, $name, $sourceClass, $fieldList = null, $detailFormFields = null, $sourceFilter = "", $sourceSort = "", $sourceJoin = "") { - Deprecation::notice('3.0', 'Use GridField with GridFieldConfig_RelationEditor'); + Deprecation::notice('3.0', 'Use GridField with GridFieldConfig_RelationEditor', Deprecation::SCOPE_CLASS); parent::__construct($controller, $name, $sourceClass, $fieldList, $detailFormFields, $sourceFilter, $sourceSort, $sourceJoin); diff --git a/forms/PasswordField.php b/forms/PasswordField.php index 44f8886b8de..6e91190f93d 100644 --- a/forms/PasswordField.php +++ b/forms/PasswordField.php @@ -11,7 +11,7 @@ class PasswordField extends TextField { * maxlength */ function __construct($name, $title = null, $value = "") { - if(count(func_get_args()) > 3) Deprecation::notice('3.0', 'Use setMaxLength() instead of constructor arguments'); + if(count(func_get_args()) > 3) Deprecation::notice('3.0', 'Use setMaxLength() instead of constructor arguments', Deprecation::SCOPE_GLOBAL); parent::__construct($name, $title, $value); } diff --git a/forms/SimpleImageField.php b/forms/SimpleImageField.php index c7b79c54344..3399b8ec8fa 100644 --- a/forms/SimpleImageField.php +++ b/forms/SimpleImageField.php @@ -69,9 +69,9 @@ class SimpleImageField extends FileField { function __construct($name, $title = null, $value = null) { - Deprecation::notice('3.0', "Use UploadField with \$myField->allowedExtensions = array('jpg', 'gif', 'png')"); + Deprecation::notice('3.0', "SimpleImageField is deprecated. Use UploadField with \$myField->allowedExtensions = array('jpg', 'gif', 'png')", Deprecation::SCOPE_CLASS); - if(count(func_get_args()) > 3) Deprecation::notice('3.0', 'Use setRightTitle() and setFolderName() instead of constructor arguments'); + if(count(func_get_args()) > 3) Deprecation::notice('3.0', 'Use setRightTitle() and setFolderName() instead of constructor arguments', Deprecation::SCOPE_GLOBAL); parent::__construct($name, $title, $value); diff --git a/i18n/i18n.php b/i18n/i18n.php index d16141e8a64..4113edc0319 100644 --- a/i18n/i18n.php +++ b/i18n/i18n.php @@ -1465,7 +1465,8 @@ static function _t($entity, $string = "", $context = "", $injection = "") { if(is_numeric($context) && in_array($context, array(PR_LOW, PR_MEDIUM, PR_HIGH))) { Deprecation::notice( '3.0', - 'The $priority argument to _t() is deprecated, please use module inclusion priorities instead' + 'The $priority argument to _t() is deprecated, please use module inclusion priorities instead', + Deprecation::SCOPE_GLOBAL ); } diff --git a/model/ComponentSet.php b/model/ComponentSet.php index 9745375d29a..a8e267f3714 100644 --- a/model/ComponentSet.php +++ b/model/ComponentSet.php @@ -4,6 +4,6 @@ */ class ComponentSet extends DataObjectSet { function setComponentInfo($type, $ownerObj, $ownerClass, $tableName, $childClass, $joinField = null) { - Deprecation::notice('3.0', 'Use ManyManyList or HasManyList instead.'); + Deprecation::notice('3.0', 'ComponentSet is deprecated. Use ManyManyList or HasManyList instead.', Deprecation::SCOPE_CLASS); } } diff --git a/model/DataExtension.php b/model/DataExtension.php index dd60da8e9ba..b2dae0611c2 100644 --- a/model/DataExtension.php +++ b/model/DataExtension.php @@ -41,7 +41,7 @@ static function add_to_class($class, $extensionClass, $args = null) { $statics = Injector::inst()->get($extensionClass, true, $args)->$extraStaticsMethod($class, $extensionClass); if ($statics) { - Deprecation::notice('3.1.0', "$extraStaticsMethod deprecated. Just define statics on your extension, or use add_to_class"); + Deprecation::notice('3.1.0', "$extraStaticsMethod deprecated. Just define statics on your extension, or use add_to_class", Deprecation::SCOPE_GLOBAL); // TODO: This currently makes extraStatics the MOST IMPORTANT config layer, not the least foreach (self::$extendable_statics as $key => $merge) { diff --git a/model/DataList.php b/model/DataList.php index d8eb9b4ba27..7711ae76a63 100644 --- a/model/DataList.php +++ b/model/DataList.php @@ -141,7 +141,7 @@ public function limit($limit, $offset = 0) { return $this; } if($limit && !is_numeric($limit)) { - Deprecation::notice('3.0', 'Please pass limits as 2 arguments, rather than an array or SQL fragment.'); + Deprecation::notice('3.0', 'Please pass limits as 2 arguments, rather than an array or SQL fragment.', Deprecation::SCOPE_GLOBAL); } $this->dataQuery->limit($limit, $offset); return $this; @@ -599,7 +599,7 @@ public function exists() { * @return DataList */ public function getRange($offset, $length) { - Deprecation::notice("3.0", 'getRange($offset, $length) is deprecated. Use limit($length, $offset) instead. Note the new argument order.'); + Deprecation::notice("3.0", 'Use limit($length, $offset) instead. Note the new argument order.'); return $this->limit($length, $offset); } diff --git a/model/DataObject.php b/model/DataObject.php index faa2f0fa925..3f10d64161b 100644 --- a/model/DataObject.php +++ b/model/DataObject.php @@ -2596,7 +2596,7 @@ public static function get($callerClass = null, $filter = "", $sort = "", $join // Todo: Determine if we can deprecate for 3.0.0 and use DI or something instead // Todo: Make the $containerClass method redundant if($containerClass != 'DataList') { - Deprecation::notice('3.0', '$containerClass argument is deprecated.'); + Deprecation::notice('3.0', 'DataObject::get() - $containerClass argument is deprecated.', Deprecation::SCOPE_GLOBAL); } $result = DataList::create($callerClass)->where($filter)->sort($sort); diff --git a/model/DataObjectDecorator.php b/model/DataObjectDecorator.php index 051f2905985..3da454b34bb 100644 --- a/model/DataObjectDecorator.php +++ b/model/DataObjectDecorator.php @@ -7,7 +7,7 @@ abstract class DataObjectDecorator extends DataExtension { public function __construct() { - Deprecation::notice('3.0', 'Use DataExtension instead.'); + Deprecation::notice('3.0', 'DataObjectDecorator is deprecated. Use DataExtension instead.', Deprecation::SCOPE_CLASS); parent::__construct(); } diff --git a/model/DataObjectSet.php b/model/DataObjectSet.php index bf1d8b2dbba..ce0dec77d23 100644 --- a/model/DataObjectSet.php +++ b/model/DataObjectSet.php @@ -10,7 +10,7 @@ class DataObjectSet extends ArrayList { * @deprecated 3.0 */ public function __construct($items = array()) { - Deprecation::notice('3.0', 'Use DataList or ArrayList instead'); + Deprecation::notice('3.0', 'DataObjectSet is deprecated. Use DataList or ArrayList instead', Deprecation::SCOPE_CLASS); if ($items) { if (!is_array($items) || func_num_args() > 1) { diff --git a/model/SQLMap.php b/model/SQLMap.php index 875af1cc0b1..ee9bb5ebe6f 100644 --- a/model/SQLMap.php +++ b/model/SQLMap.php @@ -19,7 +19,7 @@ class SQLMap extends Object implements IteratorAggregate { * @param SQLQuery $query The query to generate this map. THis isn't executed until it's needed. */ public function __construct(SQLQuery $query, $keyField = "ID", $titleField = "Title") { - Deprecation::notice('3.0', 'Use SS_Map or DataList::map() instead.'); + Deprecation::notice('3.0', 'Use SS_Map or DataList::map() instead.', Deprecation::SCOPE_CLASS); if(!$query) { user_error('SQLMap constructed with null query.', E_USER_ERROR); diff --git a/tests/dev/DeprecationTest.php b/tests/dev/DeprecationTest.php index ef77668bd37..2382e2e7ff8 100644 --- a/tests/dev/DeprecationTest.php +++ b/tests/dev/DeprecationTest.php @@ -66,13 +66,40 @@ function testMatchingModuleNotifcationVersionAffectsNotice() { $this->callThatOriginatesFromFramework(); } + function testMethodNameCalculation() { + $this->assertEquals(DeprecationTest_Deprecation::get_method(), 'DeprecationTest->testMethodNameCalculation'); + } + + /** + * @expectedException PHPUnit_Framework_Error + * @expectedExceptionMessage DeprecationTest->testScopeMethod is deprecated. Method scope + */ + function testScopeMethod() { + Deprecation::notification_version('2.0.0'); + Deprecation::notice('2.0.0', 'Method scope', Deprecation::SCOPE_METHOD); + } + + /** + * @expectedException PHPUnit_Framework_Error + * @expectedExceptionMessage DeprecationTest is deprecated. Class scope + */ + function testScopeClass() { + Deprecation::notification_version('2.0.0'); + Deprecation::notice('2.0.0', 'Class scope', Deprecation::SCOPE_CLASS); + } + + /** + * @expectedException PHPUnit_Framework_Error + * @expectedExceptionMessage Global scope + */ + function testScopeGlobal() { + Deprecation::notification_version('2.0.0'); + Deprecation::notice('2.0.0', 'Global scope', Deprecation::SCOPE_GLOBAL); + } + protected function callThatOriginatesFromFramework() { $this->assertEquals(DeprecationTest_Deprecation::get_module(), FRAMEWORK_DIR); Deprecation::notice('2.0', 'Deprecation test passed'); } - function testMethodNameCalculation() { - $this->assertEquals(DeprecationTest_Deprecation::get_method(), 'DeprecationTest->testMethodNameCalculation'); - } - }