Ticket #851 (defect)

Opened 3 months ago

Last modified 2 months ago

TPropertyAccess doesn't get properties right if an object has a __call() method

Status: new

Reported by: simon.lehmann Assigned to: xue
Priority: high Milestone: 3.1.3
Component: Prado Framework v3 Version: 3.1
Severity: major Keywords:
Cc:

TPropertyAccess tries to find a suitable getter for accessing a property by using is_callable() on the generated getter-name. This works fine, as long as an object doesn't define the magic __call() method (which every ActiveRecord has by default!). If it does, is_callable will always return true, but __call() will usually not return a requested property and thus leads to mysterious null values for properties used for example in a ParameterMap.

This was quite hard to track down, but was then quite easy to fix by checking if method_exists() and is_callable(). This can of course lead to problems when someone is (mis)using __call() for property access, but this should anyway be done with __get() and __set().

The provided patch also fixes the TPropertyAccess::has() Method (same problem here) and for consistency also changes TPropertyAccess::get().

Patch:

Index: framework/Data/SqlMap/DataMapper/TPropertyAccess.php
===================================================================
--- framework/Data/SqlMap/DataMapper/TPropertyAccess.php	(revision 2460)
+++ framework/Data/SqlMap/DataMapper/TPropertyAccess.php	(working copy)
@@ -67,7 +67,7 @@
 			else if(is_object($object))

 			{

 				$getter = 'get'.$prop;

-				if(is_callable(array($object,$getter)))

+				if(method_exists($object, $getter) && is_callable(array($object,$getter)))

 					$object = $object->{$getter}();

 				else if(in_array($prop, array_keys(get_object_vars($object))))

 					$object = $object->{$prop};

@@ -102,7 +102,7 @@
 			else if(is_object($object))

 			{

 				$getter = 'get'.$prop;

-				if(is_callable(array($object,$getter)))

+				if(method_exists($object, $getter) && is_callable(array($object,$getter)))

 					$object = $object->{$getter}();

 				else if(in_array($prop, array_keys(get_object_vars($object))))

 					$object = $object->{$prop};

@@ -137,7 +137,7 @@
 		else if(is_object($object))

 		{

 			$setter = 'set'.$prop;

-			if (method_exists($object,$setter))

+			if (method_exists($object, $setter) && is_callable(array($object,$setter)))

 				$object->{$setter}($value);

 			else

 				$object->{$prop} = $value;

Attachments

TPropertyAccess_r2382.patch (1.2 kB) - added by simon.lehmann on 05/09/2008 10:15:59 AM.
Patch as a file

Change History

05/09/2008 10:15:59 AM: Modified by simon.lehmann

  • attachment TPropertyAccess_r2382.patch added.

Patch as a file

05/13/2008 07:50:23 AM: Modified by tof06

  • milestone set to 3.1.3.