Skip to content

Commit

Permalink
Merge pull request magento#1673 from magento-engcom/2.2-develop-prs
Browse files Browse the repository at this point in the history
Public Pull Requests

magento#11879 magento#4004: Newsletter Subscriber create-date not set, and change_status_at broken by @nemesis-back
magento#11556 Fix magento#10583: Checkout place order exception when using a new address by @joni-jones

Fixed Public Issues

magento#4004 Newsletter Subscriber create-date not set, and change_status_at broken
magento#10583 Checkout place order exception when using a new address
  • Loading branch information
Oleksii Korshenko authored Nov 7, 2017
2 parents c896f2c + 5109d8c commit dbcc3c4
Show file tree
Hide file tree
Showing 7 changed files with 165 additions and 23 deletions.
31 changes: 28 additions & 3 deletions app/code/Magento/Newsletter/Model/Subscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@

use Magento\Customer\Api\AccountManagementInterface;
use Magento\Customer\Api\CustomerRepositoryInterface;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\Exception\MailException;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\Stdlib\DateTime\DateTime;

/**
* Subscriber model
Expand Down Expand Up @@ -94,6 +96,12 @@ class Subscriber extends \Magento\Framework\Model\AbstractModel
*/
protected $_customerSession;

/**
* Date
* @var DateTime
*/
private $dateTime;

/**
* Store manager
*
Expand Down Expand Up @@ -134,9 +142,10 @@ class Subscriber extends \Magento\Framework\Model\AbstractModel
* @param CustomerRepositoryInterface $customerRepository
* @param AccountManagementInterface $customerAccountManagement
* @param \Magento\Framework\Translate\Inline\StateInterface $inlineTranslation
* @param \Magento\Framework\Model\ResourceModel\AbstractResource $resource
* @param \Magento\Framework\Data\Collection\AbstractDb $resourceCollection
* @param \Magento\Framework\Model\ResourceModel\AbstractResource|null $resource
* @param \Magento\Framework\Data\Collection\AbstractDb|null $resourceCollection
* @param array $data
* @param DateTime|null $dateTime
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
public function __construct(
Expand All @@ -152,7 +161,8 @@ public function __construct(
\Magento\Framework\Translate\Inline\StateInterface $inlineTranslation,
\Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
\Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
array $data = []
array $data = [],
DateTime $dateTime = null
) {
$this->_newsletterData = $newsletterData;
$this->_scopeConfig = $scopeConfig;
Expand All @@ -162,6 +172,7 @@ public function __construct(
$this->customerRepository = $customerRepository;
$this->customerAccountManagement = $customerAccountManagement;
$this->inlineTranslation = $inlineTranslation;
$this->dateTime = $dateTime ?: ObjectManager::getInstance()->get(DateTime::class);
parent::__construct($context, $registry, $resource, $resourceCollection, $data);
}

Expand Down Expand Up @@ -810,4 +821,18 @@ public function getSubscriberFullName()
}
return $name;
}

/**
* Set date of last changed status
*
* @return $this
*/
public function beforeSave()
{
parent::beforeSave();
if ($this->dataHasChangedFor('subscriber_status')) {
$this->setChangeStatusAt($this->dateTime->gmtDate());
}
return $this;
}
}
2 changes: 1 addition & 1 deletion app/code/Magento/Quote/Model/Quote.php
Original file line number Diff line number Diff line change
Expand Up @@ -1057,7 +1057,7 @@ public function addCustomerAddress(\Magento\Customer\Api\Data\AddressInterface $
public function updateCustomerData(\Magento\Customer\Api\Data\CustomerInterface $customer)
{
$quoteCustomer = $this->getCustomer();
$this->dataObjectHelper->mergeDataObjects(get_class($quoteCustomer), $quoteCustomer, $customer);
$this->dataObjectHelper->mergeDataObjects(CustomerInterface::class, $quoteCustomer, $customer);
$this->setCustomer($quoteCustomer);
return $this;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ protected function _getCustomerDataArray()
\Magento\Customer\Model\Data\Customer::DOB => '2014-02-03 00:00:00',
\Magento\Customer\Model\Data\Customer::EMAIL => 'qa@example.com',
\Magento\Customer\Model\Data\Customer::FIRSTNAME => 'Joe',
\Magento\Customer\Model\Data\Customer::GENDER => 'Male',
\Magento\Customer\Model\Data\Customer::GENDER => 0,
\Magento\Customer\Model\Data\Customer::GROUP_ID =>
\Magento\Customer\Model\GroupManagement::NOT_LOGGED_IN_ID,
\Magento\Customer\Model\Data\Customer::ID => 1,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Magento\Framework\Reflection\Test\Unit\Fixture;

class TSample implements TSampleInterface
{
/**
* @inheritdoc
*/
public function getPropertyName()
{
return '';
}

/**
* @inheritdoc
*/
public function getName()
{
return '';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Magento\Framework\Reflection\Test\Unit\Fixture;

interface TSampleInterface
{
/**
* Returns property name for a sample.
*
* @return string
*/
public function getPropertyName();

/**
* Doc block without return tag.
*/
public function getName();
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
// @codingStandardsIgnoreStart
namespace Magento\Framework\Reflection\Test\Unit;

use Zend\Code\Reflection\ClassReflection;
use Magento\Framework\Exception\SerializationException;
use Magento\Framework\Reflection\Test\Unit\Fixture\TSample;
use Zend\Code\Reflection\ClassReflection;

/**
* Type processor Test
Expand Down Expand Up @@ -260,4 +261,35 @@ public function testGetOperationName()
{
$this->assertEquals("resNameMethodName", $this->_typeProcessor->getOperationName("resName", "methodName"));
}

/**
* Checks a case when method has only `@inheritdoc` annotation.
*/
public function testGetReturnTypeWithInheritDocBlock()
{
$expected = [
'type' => 'string',
'isRequired' => true,
'description' => null,
'parameterCount' => 0
];

$classReflection = new ClassReflection(TSample::class);
$methodReflection = $classReflection->getMethod('getPropertyName');

self::assertEquals($expected, $this->_typeProcessor->getGetterReturnType($methodReflection));
}

/**
* Checks a case when method and parent interface don't have `@return` annotation.
*
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage Getter return type must be specified using @return annotation. See Magento\Framework\Reflection\Test\Unit\Fixture\TSample::getName()
*/
public function testGetReturnTypeWithoutReturnTag()
{
$classReflection = new ClassReflection(TSample::class);
$methodReflection = $classReflection->getMethod('getName');
$this->_typeProcessor->getGetterReturnType($methodReflection);
}
}
73 changes: 56 additions & 17 deletions lib/internal/Magento/Framework/Reflection/TypeProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Magento\Framework\Exception\SerializationException;
use Magento\Framework\Phrase;
use Zend\Code\Reflection\ClassReflection;
use Zend\Code\Reflection\DocBlock\Tag\ReturnTag;
use Zend\Code\Reflection\DocBlockReflection;
use Zend\Code\Reflection\MethodReflection;
use Zend\Code\Reflection\ParameterReflection;
Expand All @@ -16,6 +17,7 @@
* Type processor of config reader properties
*
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
* @SuppressWarnings(PHPMD.ExcessiveClassComplexity) this suppress MUST be removed after removing deprecated methods.
*/
class TypeProcessor
{
Expand Down Expand Up @@ -275,22 +277,7 @@ protected function dataObjectGetterDescriptionToFieldDescription($shortDescripti
*/
public function getGetterReturnType($methodReflection)
{
$methodDocBlock = $methodReflection->getDocBlock();
if (!$methodDocBlock) {
throw new \InvalidArgumentException(
"Each getter must have description with @return annotation. "
. "See {$methodReflection->getDeclaringClass()->getName()}::{$methodReflection->getName()}()"
);
}
$returnAnnotations = $methodDocBlock->getTags('return');
if (empty($returnAnnotations)) {
throw new \InvalidArgumentException(
"Getter return type must be specified using @return annotation. "
. "See {$methodReflection->getDeclaringClass()->getName()}::{$methodReflection->getName()}()"
);
}
/** @var \Zend\Code\Reflection\DocBlock\Tag\ReturnTag $returnAnnotation */
$returnAnnotation = current($returnAnnotations);
$returnAnnotation = $this->getMethodReturnAnnotation($methodReflection);
$types = $returnAnnotation->getTypes();
$returnType = current($types);
$nullable = in_array('null', $types);
Expand Down Expand Up @@ -362,7 +349,7 @@ public function isTypeSimple($type)
self::NORMALIZED_INT_TYPE,
self::NORMALIZED_FLOAT_TYPE,
self::NORMALIZED_DOUBLE_TYPE,
self::NORMALIZED_BOOLEAN_TYPE
self::NORMALIZED_BOOLEAN_TYPE,
]
);
}
Expand Down Expand Up @@ -708,4 +695,56 @@ private function getNormalizedType($type)
}
return $type;
}

/**
* Parses `return` annotation from reflection method.
*
* @param MethodReflection $methodReflection
* @return ReturnTag
* @throws \InvalidArgumentException if doc block is empty or `@return` annotation doesn't exist
*/
private function getMethodReturnAnnotation(MethodReflection $methodReflection)
{
$methodName = $methodReflection->getName();
$returnAnnotations = $this->getReturnFromDocBlock($methodReflection);
if (empty($returnAnnotations)) {
// method can inherit doc block from implemented interface, like for interceptors
$implemented = $methodReflection->getDeclaringClass()->getInterfaces();
/** @var ClassReflection $parentClassReflection */
foreach ($implemented as $parentClassReflection) {
if ($parentClassReflection->hasMethod($methodName)) {
$returnAnnotations = $this->getReturnFromDocBlock(
$parentClassReflection->getMethod($methodName)
);
break;
}
}
// throw an exception if even implemented interface doesn't have return annotations
if (empty($returnAnnotations)) {
throw new \InvalidArgumentException(
"Getter return type must be specified using @return annotation. "
. "See {$methodReflection->getDeclaringClass()->getName()}::{$methodName}()"
);
}
}
return $returnAnnotations;
}

/**
* Parses `return` annotation from doc block.
*
* @param MethodReflection $methodReflection
* @return ReturnTag
*/
private function getReturnFromDocBlock(MethodReflection $methodReflection)
{
$methodDocBlock = $methodReflection->getDocBlock();
if (!$methodDocBlock) {
throw new \InvalidArgumentException(
"Each getter must have a doc block. "
. "See {$methodReflection->getDeclaringClass()->getName()}::{$methodReflection->getName()}()"
);
}
return current($methodDocBlock->getTags('return'));
}
}

0 comments on commit dbcc3c4

Please sign in to comment.