From 71a6a88de82d23232cdf5377a44804a5f55d29b8 Mon Sep 17 00:00:00 2001
From: Marco Pivetta <ocramius@gmail.com>
Date: Sun, 18 Jan 2015 00:53:34 +0100
Subject: [PATCH] #1228 DDC-3490 -better/more complete exception message for
 invalid populated associations

---
 .../ORM/ORMInvalidArgumentException.php       | 31 +++++++++++++++----
 1 file changed, 25 insertions(+), 6 deletions(-)

diff --git a/lib/Doctrine/ORM/ORMInvalidArgumentException.php b/lib/Doctrine/ORM/ORMInvalidArgumentException.php
index d0089d752..633ff5c60 100644
--- a/lib/Doctrine/ORM/ORMInvalidArgumentException.php
+++ b/lib/Doctrine/ORM/ORMInvalidArgumentException.php
@@ -18,6 +18,7 @@
  */
 
 namespace Doctrine\ORM;
+use Doctrine\ORM\Mapping\ClassMetadata;
 
 /**
  * Contains exception messages for all invalid lifecycle state exceptions inside UnitOfWork
@@ -195,18 +196,36 @@ class ORMInvalidArgumentException extends \InvalidArgumentException
      */
     public static function computeAssociationChangesError($relation, $fieldname, $value)
     {
-        return new self(sprintf('Expected an Object for relation %s::%s got %s instead.', get_class($relation), $fieldname, gettype($value)));
+        return new self(sprintf(
+            'Expected an Object for relation %s::%s got %s instead.',
+            get_class($relation),
+            $fieldname,
+            is_object($value) ? get_class($value) : gettype($value)
+        ));
     }
 
     /**
-     * @param \Doctrine\ORM\Mapping\ClassMetadata $targetClass
-     * @param array $assoc
-     * @param mixed $entry
+     * @param ClassMetadata $targetClass
+     * @param array         $assoc
+     * @param mixed         $actualValue
+     *
      * @return self
      */
-    public static function invalidAssociation($targetClass, $assoc, $entry)
+    public static function invalidAssociation(ClassMetadata $targetClass, $assoc, $actualValue)
     {
-        return new self(gettype($entry) . (is_scalar($entry) ? ' "'.$entry.'"': '') . ' is not an Object.');
+        $expectedType = 'Doctrine\Common\Collections\Collection|array';
+
+        if (($assoc['type'] & ClassMetadata::TO_ONE) > 0) {
+            $expectedType = $targetClass->getName();
+        }
+
+        return new self(sprintf(
+            'Expected value of type "%s" for association field "%s#$%s", got "%s" instead.',
+            $expectedType,
+            $assoc['sourceEntity'],
+            $assoc['fieldName'],
+            is_object($actualValue) ? get_class($actualValue) : gettype($actualValue)
+        ));
     }
 
     /**