From a1929d2372052728a1961586311372f8aaf6d4a1 Mon Sep 17 00:00:00 2001 From: Mykhailo Kudelia Date: Wed, 29 Apr 2015 15:28:39 +0300 Subject: [PATCH 01/47] CRM-2965: add description to activity list item --- .../Entity/ActivityList.php | 32 ++++++++++ .../Entity/Manager/ActivityListManager.php | 1 + .../Schema/v1_2/AddActivityDescription.php | 30 +++++++++ .../Model/ActivityListProviderInterface.php | 7 +++ .../Provider/ActivityListChainProvider.php | 17 +++++ .../views/ActivityList/js/view.js.twig | 3 + .../Tests/Unit/Entity/ActivityListTest.php | 1 + .../Manager/ActivityListManagerTest.php | 2 + .../ActivityListChainProviderTest.php | 8 +++ .../Provider/Fixture/TestActivityProvider.php | 8 +++ .../CalendarEventActivityListProvider.php | 9 +++ .../Provider/EmailActivityListProvider.php | 30 ++++++++- .../EmailBundle/Resources/config/services.yml | 5 ++ .../Tests/Unit/Tools/EmailHelperTest.php | 63 +++++++++++++++++++ .../Bundle/EmailBundle/Tools/EmailHelper.php | 57 +++++++++++++++++ .../Provider/NoteActivityListProvider.php | 9 +++ 16 files changed, 281 insertions(+), 1 deletion(-) create mode 100644 src/Oro/Bundle/ActivityListBundle/Migrations/Schema/v1_2/AddActivityDescription.php create mode 100644 src/Oro/Bundle/EmailBundle/Tests/Unit/Tools/EmailHelperTest.php create mode 100644 src/Oro/Bundle/EmailBundle/Tools/EmailHelper.php diff --git a/src/Oro/Bundle/ActivityListBundle/Entity/ActivityList.php b/src/Oro/Bundle/ActivityListBundle/Entity/ActivityList.php index bd52b9f8b03..076f795951e 100644 --- a/src/Oro/Bundle/ActivityListBundle/Entity/ActivityList.php +++ b/src/Oro/Bundle/ActivityListBundle/Entity/ActivityList.php @@ -91,6 +91,14 @@ class ActivityList extends ExtendActivityList */ protected $subject; + /** + * @var string + * + * @ORM\Column(name="description", type="text") + * @Soap\ComplexType("string", nillable=true) + */ + protected $description; + /** * @var bool * @@ -217,6 +225,30 @@ public function setSubject($subject) return $this; } + /** + * Get a description of the related record + * + * @return string + */ + public function getDescription() + { + return $this->description; + } + + /** + * Set a description of the related record + * + * @param string $description + * + * @return self + */ + public function setDescription($description) + { + $this->description = $description; + + return $this; + } + /** * Get head item in the thread * diff --git a/src/Oro/Bundle/ActivityListBundle/Entity/Manager/ActivityListManager.php b/src/Oro/Bundle/ActivityListBundle/Entity/Manager/ActivityListManager.php index 7e9043d287c..7f6a1d267e0 100644 --- a/src/Oro/Bundle/ActivityListBundle/Entity/Manager/ActivityListManager.php +++ b/src/Oro/Bundle/ActivityListBundle/Entity/Manager/ActivityListManager.php @@ -206,6 +206,7 @@ public function getEntityViewModel(ActivityList $entity, $targetEntityData = []) 'editor_id' => $editorId, 'verb' => $entity->getVerb(), 'subject' => $entity->getSubject(), + 'description' => $entity->getDescription(), 'data' => $data, 'relatedActivityClass' => $entity->getRelatedActivityClass(), 'relatedActivityId' => $entity->getRelatedActivityId(), diff --git a/src/Oro/Bundle/ActivityListBundle/Migrations/Schema/v1_2/AddActivityDescription.php b/src/Oro/Bundle/ActivityListBundle/Migrations/Schema/v1_2/AddActivityDescription.php new file mode 100644 index 00000000000..8616d4139b4 --- /dev/null +++ b/src/Oro/Bundle/ActivityListBundle/Migrations/Schema/v1_2/AddActivityDescription.php @@ -0,0 +1,30 @@ +getTable('oro_activity_list'); + $table->addColumn('description', 'text', ['notnull' => false]); + } +} diff --git a/src/Oro/Bundle/ActivityListBundle/Model/ActivityListProviderInterface.php b/src/Oro/Bundle/ActivityListBundle/Model/ActivityListProviderInterface.php index 8c1e3268be9..4101c460c21 100644 --- a/src/Oro/Bundle/ActivityListBundle/Model/ActivityListProviderInterface.php +++ b/src/Oro/Bundle/ActivityListBundle/Model/ActivityListProviderInterface.php @@ -26,6 +26,13 @@ public function isApplicableTarget(ConfigIdInterface $configId, ConfigManager $c */ public function getSubject($entity); + /** + * @param object $entity + * + * @return string + */ + public function getDescription($entity); + /** * @param ActivityList $activityListEntity * diff --git a/src/Oro/Bundle/ActivityListBundle/Provider/ActivityListChainProvider.php b/src/Oro/Bundle/ActivityListBundle/Provider/ActivityListChainProvider.php index 0bf645a2512..7546d143d31 100644 --- a/src/Oro/Bundle/ActivityListBundle/Provider/ActivityListChainProvider.php +++ b/src/Oro/Bundle/ActivityListBundle/Provider/ActivityListChainProvider.php @@ -213,6 +213,22 @@ public function getSubject($entity) return null; } + /** + * @param object $entity + * + * @return string|null + */ + public function getDescription($entity) + { + foreach ($this->providers as $provider) { + if ($provider->isApplicable($entity)) { + return $provider->getDescription($entity); + } + } + + return null; + } + /** * Get activity list provider for given activity entity * @@ -257,6 +273,7 @@ protected function getActivityListEntityForEntity( } $list->setSubject($provider->getSubject($entity)); + $list->setDescription($provider->getDescription($entity)); if ($this->hasCustomDate($provider)) { $list->setCreatedAt($provider->getDate($entity)); $list->setUpdatedAt($provider->getDate($entity)); diff --git a/src/Oro/Bundle/ActivityListBundle/Resources/views/ActivityList/js/view.js.twig b/src/Oro/Bundle/ActivityListBundle/Resources/views/ActivityList/js/view.js.twig index 968542e155c..e106d96e686 100644 --- a/src/Oro/Bundle/ActivityListBundle/Resources/views/ActivityList/js/view.js.twig +++ b/src/Oro/Bundle/ActivityListBundle/Resources/views/ActivityList/js/view.js.twig @@ -27,6 +27,9 @@
{% block activityShortMessage %} <%= subject %> + <% if (description) { %> + - <%= description %> + <% } %> {% endblock %}
diff --git a/src/Oro/Bundle/ActivityListBundle/Tests/Unit/Entity/ActivityListTest.php b/src/Oro/Bundle/ActivityListBundle/Tests/Unit/Entity/ActivityListTest.php index 780f94ba7d2..709c6b13aa2 100644 --- a/src/Oro/Bundle/ActivityListBundle/Tests/Unit/Entity/ActivityListTest.php +++ b/src/Oro/Bundle/ActivityListBundle/Tests/Unit/Entity/ActivityListTest.php @@ -50,6 +50,7 @@ public function getSetDataProvider() return [ ['verb', 'testVerb'], ['subject', 'testSubject'], + ['description', 'testDescription'], ['relatedActivityClass', 'testRelatedActivityClass'], ['relatedActivityId', 123], ['updatedAt', new \DateTime('now')], diff --git a/src/Oro/Bundle/ActivityListBundle/Tests/Unit/Entity/Manager/ActivityListManagerTest.php b/src/Oro/Bundle/ActivityListBundle/Tests/Unit/Entity/Manager/ActivityListManagerTest.php index 7f94e686daa..6c655dcb80f 100644 --- a/src/Oro/Bundle/ActivityListBundle/Tests/Unit/Entity/Manager/ActivityListManagerTest.php +++ b/src/Oro/Bundle/ActivityListBundle/Tests/Unit/Entity/Manager/ActivityListManagerTest.php @@ -212,6 +212,7 @@ public function testGetItem() $testItem->setUpdatedAt(new \DateTime('2014-01-01', new \DateTimeZone('UTC'))); $testItem->setVerb(ActivityList::VERB_UPDATE); $testItem->setSubject('test_subject'); + $testItem->setDescription('test_description'); $testItem->setRelatedActivityClass('Acme\TestBundle\Entity\TestEntity'); $testItem->setRelatedActivityId(127); @@ -245,6 +246,7 @@ function ($user) { 'editor_id' => 142, 'verb' => 'update', 'subject' => 'test_subject', + 'description' => 'test_description', 'data' => ['test_data'], 'relatedActivityClass' => 'Acme\TestBundle\Entity\TestEntity', 'relatedActivityId' => 127, diff --git a/src/Oro/Bundle/ActivityListBundle/Tests/Unit/Provider/ActivityListChainProviderTest.php b/src/Oro/Bundle/ActivityListBundle/Tests/Unit/Provider/ActivityListChainProviderTest.php index 138acbe8a61..01d62cdf1ca 100644 --- a/src/Oro/Bundle/ActivityListBundle/Tests/Unit/Provider/ActivityListChainProviderTest.php +++ b/src/Oro/Bundle/ActivityListBundle/Tests/Unit/Provider/ActivityListChainProviderTest.php @@ -90,6 +90,13 @@ public function testGetSubject() $this->assertEquals('test', $this->provider->getSubject($testEntity)); } + public function testGetDescription() + { + $testEntity = new \stdClass(); + $testEntity->description = 'test'; + $this->assertEquals('test', $this->provider->getDescription($testEntity)); + } + public function testGetEmptySubject() { $testEntity = new TestTarget(); @@ -170,6 +177,7 @@ public function testGetUpdatedActivityList() $testEntity = new \stdClass(); $testEntity->subject = 'testSubject'; + $testEntity->description = 'testDescription'; $this->testActivityProvider->setTargets([new \stdClass()]); $this->doctrineHelper->expects($this->any()) diff --git a/src/Oro/Bundle/ActivityListBundle/Tests/Unit/Provider/Fixture/TestActivityProvider.php b/src/Oro/Bundle/ActivityListBundle/Tests/Unit/Provider/Fixture/TestActivityProvider.php index ba05b29bfd1..69b52a2ed36 100644 --- a/src/Oro/Bundle/ActivityListBundle/Tests/Unit/Provider/Fixture/TestActivityProvider.php +++ b/src/Oro/Bundle/ActivityListBundle/Tests/Unit/Provider/Fixture/TestActivityProvider.php @@ -34,6 +34,14 @@ public function getSubject($entity) return $entity->subject; } + /** + * {@inheritdoc} + */ + public function getDescription($entity) + { + return $entity->description; + } + /** * {@inheritdoc} */ diff --git a/src/Oro/Bundle/CalendarBundle/Provider/CalendarEventActivityListProvider.php b/src/Oro/Bundle/CalendarBundle/Provider/CalendarEventActivityListProvider.php index c985ff632d7..ba3e364ec0b 100644 --- a/src/Oro/Bundle/CalendarBundle/Provider/CalendarEventActivityListProvider.php +++ b/src/Oro/Bundle/CalendarBundle/Provider/CalendarEventActivityListProvider.php @@ -65,6 +65,15 @@ public function getSubject($entity) return $entity->getTitle(); } + /** + * @param object $entity + * @return null + */ + public function getDescription($entity) + { + return null; + } + /** * {@inheritdoc} */ diff --git a/src/Oro/Bundle/EmailBundle/Provider/EmailActivityListProvider.php b/src/Oro/Bundle/EmailBundle/Provider/EmailActivityListProvider.php index df03adde84e..fe9d0825fcc 100644 --- a/src/Oro/Bundle/EmailBundle/Provider/EmailActivityListProvider.php +++ b/src/Oro/Bundle/EmailBundle/Provider/EmailActivityListProvider.php @@ -18,6 +18,7 @@ use Oro\Bundle\EntityConfigBundle\Config\Id\ConfigIdInterface; use Oro\Bundle\EntityConfigBundle\DependencyInjection\Utils\ServiceLink; use Oro\Bundle\CommentBundle\Model\CommentProviderInterface; +use Oro\Bundle\EmailBundle\Tools\EmailHelper; class EmailActivityListProvider implements ActivityListProviderInterface, @@ -26,6 +27,7 @@ class EmailActivityListProvider implements CommentProviderInterface { const ACTIVITY_CLASS = 'Oro\Bundle\EmailBundle\Entity\Email'; + const MAX_DESCRIPTION_LENGTH = 80; /** @var DoctrineHelper */ protected $doctrineHelper; @@ -45,6 +47,11 @@ class EmailActivityListProvider implements /** @var EmailThreadProvider */ protected $emailThreadProvider; + /** + * @var EmailHelper + */ + protected $emailHelper; + /** * @param DoctrineHelper $doctrineHelper * @param ServiceLink $doctrineRegistryLink @@ -59,7 +66,8 @@ public function __construct( ServiceLink $nameFormatterLink, Router $router, ConfigManager $configManager, - EmailThreadProvider $emailThreadProvider + EmailThreadProvider $emailThreadProvider, + EmailHelper $emailHelper ) { $this->doctrineHelper = $doctrineHelper; $this->doctrineRegistryLink = $doctrineRegistryLink; @@ -67,6 +75,7 @@ public function __construct( $this->router = $router; $this->configManager = $configManager; $this->emailThreadProvider = $emailThreadProvider; + $this->emailHelper = $emailHelper; } /** @@ -109,6 +118,25 @@ public function getSubject($entity) return $entity->getSubject(); } + /** + * {@inheritdoc} + */ + public function getDescription($entity) + { + /** @var $entity Email */ + if ($entity->getEmailBody()) { + + $body = $entity->getEmailBody(); + $content = $this->emailHelper->getOnlyLastAnswer($body); + $content = $this->emailHelper->getStrippedBody($content); + $content = $this->emailHelper->getShortBody($content, self::MAX_DESCRIPTION_LENGTH); + + return $content; + } + + return null; + } + /** * {@inheritdoc} */ diff --git a/src/Oro/Bundle/EmailBundle/Resources/config/services.yml b/src/Oro/Bundle/EmailBundle/Resources/config/services.yml index 3716747aa66..7cc722cd588 100644 --- a/src/Oro/Bundle/EmailBundle/Resources/config/services.yml +++ b/src/Oro/Bundle/EmailBundle/Resources/config/services.yml @@ -4,6 +4,7 @@ parameters: oro_email.email_folder.model.class: Oro\Bundle\EmailBundle\Model\FolderType oro_email.email.cache.manager.class: Oro\Bundle\EmailBundle\Cache\EmailCacheManager oro_email.email_holder_helper.class: Oro\Bundle\EmailBundle\Tools\EmailHolderHelper + oro_email.email_helper.class: Oro\Bundle\EmailBundle\Tools\EmailHelper oro_email.email.address.helper.class: Oro\Bundle\EmailBundle\Tools\EmailAddressHelper oro_email.email.address.manager.class: Oro\Bundle\EmailBundle\Entity\Manager\EmailAddressManager oro_email.email.owner.provider.class: Oro\Bundle\EmailBundle\Entity\Provider\EmailOwnerProvider @@ -114,6 +115,9 @@ services: arguments: - @oro_entity_config.provider.extend + oro_email.email_helper: + class: %oro_email.email_helper.class% + oro_email.email.address.helper: class: %oro_email.email.address.helper.class% @@ -491,6 +495,7 @@ services: - @router - @oro_entity_config.config_manager - @oro_email.email.thread.provider + - @oro_email.email_helper tags: - {name: oro_activity_list.provider, priority: 30} diff --git a/src/Oro/Bundle/EmailBundle/Tests/Unit/Tools/EmailHelperTest.php b/src/Oro/Bundle/EmailBundle/Tests/Unit/Tools/EmailHelperTest.php new file mode 100644 index 00000000000..230998ee43c --- /dev/null +++ b/src/Oro/Bundle/EmailBundle/Tests/Unit/Tools/EmailHelperTest.php @@ -0,0 +1,63 @@ +helper = new EmailHelper(); + } + + public function testGetStrippedBody() + { + $actualString = '
test
'; + $expectedString = strip_tags($actualString); + + $this->assertEquals($expectedString, $this->helper->getStrippedBody($actualString)); + } + + /** + * @dataProvider bodiesProvider + */ + public function testGetOnlyLastAnswer($expected, $actual, $isTextContent) + { + $body = new EmailBody(); + $body->setBodyContent($actual); + $body->setBodyIsText($isTextContent); + + $this->assertEquals($expected, $this->helper->getOnlyLastAnswer($body)); + } + + /** + * @dataProvider shortBodiesProvider + */ + public function testGetShortBody($expected, $actual, $maxLength) + { + $this->assertEquals($expected, $this->helper->getShortBody($actual, $maxLength)); + } + + public static function bodiesProvider() + { + return array( + array('

Hello

', '

Hello

', false), + array('

Hello

', '

Hello

Other content
', false), + array('

H

H
', '

H

H
', true) + ); + } + + public static function shortBodiesProvider() + { + return array( + array('abc abc abc...', 'abc abc abc abc', 13), + array('abc abc abc abc', 'abc abc abc abc', 16), + array('abcabcabca...', 'abcabcabcabc', 10), + ); + } +} diff --git a/src/Oro/Bundle/EmailBundle/Tools/EmailHelper.php b/src/Oro/Bundle/EmailBundle/Tools/EmailHelper.php new file mode 100644 index 00000000000..790da43a047 --- /dev/null +++ b/src/Oro/Bundle/EmailBundle/Tools/EmailHelper.php @@ -0,0 +1,57 @@ +getBodyIsText()) { + preg_match('/(.+)(
)/siU', $body->getBodyContent(), $match); + + if (isset($match[1])) { + return $match[1]; + } + } + + return $body->getBodyContent(); + } + + /** + * Get shorter email body + * + * @param string $content + * @param int $maxLength + * @return string + */ + public function getShortBody($content, $maxLength = 60) + { + if (mb_strlen($content) > $maxLength) { + $content = mb_substr($content, 0, $maxLength); + $lastOccurrencePos = strrpos($content, ' '); + if ($lastOccurrencePos !== false) { + $content = mb_substr($content, 0, $lastOccurrencePos); + } + $content .= '...'; + } + + return $content; + } +} diff --git a/src/Oro/Bundle/NoteBundle/Provider/NoteActivityListProvider.php b/src/Oro/Bundle/NoteBundle/Provider/NoteActivityListProvider.php index d14915b9391..8303fa87d5f 100644 --- a/src/Oro/Bundle/NoteBundle/Provider/NoteActivityListProvider.php +++ b/src/Oro/Bundle/NoteBundle/Provider/NoteActivityListProvider.php @@ -67,6 +67,15 @@ public function getSubject($entity) return $this->truncate(strip_tags($entity->getMessage()), 100); } + /** + * @param object $entity + * @return null + */ + public function getDescription($entity) + { + return null; + } + /** * {@inheritdoc} */ From 193498420027dcd6e7268faabe831488a51cd8dd Mon Sep 17 00:00:00 2001 From: Makar Sichevoy Date: Thu, 30 Apr 2015 11:40:17 +0300 Subject: [PATCH 02/47] CRM-2965: Add description to activity list item --- src/Oro/Bundle/UIBundle/Twig/HtmlTagExtension.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Oro/Bundle/UIBundle/Twig/HtmlTagExtension.php b/src/Oro/Bundle/UIBundle/Twig/HtmlTagExtension.php index 39fa22e15f3..49255ac42cf 100644 --- a/src/Oro/Bundle/UIBundle/Twig/HtmlTagExtension.php +++ b/src/Oro/Bundle/UIBundle/Twig/HtmlTagExtension.php @@ -49,7 +49,7 @@ public function tagFilter($string) } /** - * Filter is inteded to purify script, style etc tags and content of them + * Filter is intended to purify script, style etc tags and content of them * * @param string $string * @return string From 0571afa0c9f6fa5c2838d6fe6edec285af943808 Mon Sep 17 00:00:00 2001 From: Mykhailo Kudelia Date: Thu, 30 Apr 2015 12:26:44 +0300 Subject: [PATCH 03/47] CRM-2965: CR --- .../Model/ActivityListProviderInterface.php | 2 +- .../CalendarEventActivityListProvider.php | 3 +-- .../EmailBundle/Resources/config/services.yml | 2 ++ .../Tests/Unit/Tools/EmailHelperTest.php | 4 ++-- .../Bundle/EmailBundle/Tools/EmailHelper.php | 17 +++++++++++++++++ .../Provider/NoteActivityListProvider.php | 3 +-- 6 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/Oro/Bundle/ActivityListBundle/Model/ActivityListProviderInterface.php b/src/Oro/Bundle/ActivityListBundle/Model/ActivityListProviderInterface.php index 4101c460c21..25abf9e62ec 100644 --- a/src/Oro/Bundle/ActivityListBundle/Model/ActivityListProviderInterface.php +++ b/src/Oro/Bundle/ActivityListBundle/Model/ActivityListProviderInterface.php @@ -29,7 +29,7 @@ public function getSubject($entity); /** * @param object $entity * - * @return string + * @return string|null */ public function getDescription($entity); diff --git a/src/Oro/Bundle/CalendarBundle/Provider/CalendarEventActivityListProvider.php b/src/Oro/Bundle/CalendarBundle/Provider/CalendarEventActivityListProvider.php index ba3e364ec0b..03f58d707c5 100644 --- a/src/Oro/Bundle/CalendarBundle/Provider/CalendarEventActivityListProvider.php +++ b/src/Oro/Bundle/CalendarBundle/Provider/CalendarEventActivityListProvider.php @@ -66,8 +66,7 @@ public function getSubject($entity) } /** - * @param object $entity - * @return null + * {@inheritdoc} */ public function getDescription($entity) { diff --git a/src/Oro/Bundle/EmailBundle/Resources/config/services.yml b/src/Oro/Bundle/EmailBundle/Resources/config/services.yml index 7cc722cd588..454abdb6d87 100644 --- a/src/Oro/Bundle/EmailBundle/Resources/config/services.yml +++ b/src/Oro/Bundle/EmailBundle/Resources/config/services.yml @@ -117,6 +117,8 @@ services: oro_email.email_helper: class: %oro_email.email_helper.class% + arguments: + - %kernel.cache_dir% oro_email.email.address.helper: class: %oro_email.email.address.helper.class% diff --git a/src/Oro/Bundle/EmailBundle/Tests/Unit/Tools/EmailHelperTest.php b/src/Oro/Bundle/EmailBundle/Tests/Unit/Tools/EmailHelperTest.php index 230998ee43c..5acffe5343c 100644 --- a/src/Oro/Bundle/EmailBundle/Tests/Unit/Tools/EmailHelperTest.php +++ b/src/Oro/Bundle/EmailBundle/Tests/Unit/Tools/EmailHelperTest.php @@ -17,8 +17,8 @@ protected function setUp() public function testGetStrippedBody() { - $actualString = '
test
'; - $expectedString = strip_tags($actualString); + $actualString = '
test
'; + $expectedString = 'test'; $this->assertEquals($expectedString, $this->helper->getStrippedBody($actualString)); } diff --git a/src/Oro/Bundle/EmailBundle/Tools/EmailHelper.php b/src/Oro/Bundle/EmailBundle/Tools/EmailHelper.php index 790da43a047..c9b65c361da 100644 --- a/src/Oro/Bundle/EmailBundle/Tools/EmailHelper.php +++ b/src/Oro/Bundle/EmailBundle/Tools/EmailHelper.php @@ -2,16 +2,33 @@ namespace Oro\Bundle\EmailBundle\Tools; +use Oro\Bundle\FormBundle\Form\DataTransformer\SanitizeHTMLTransformer; + use Oro\Bundle\EmailBundle\Entity\EmailBody; class EmailHelper { + /** + * @var string + */ + protected $cacheDir; + + /** + * @param string|null $cacheDir + */ + public function __construct($cacheDir = null) + { + $this->cacheDir = $cacheDir; + } + /** * @param string $content * @return string */ public function getStrippedBody($content) { + $transformer = new SanitizeHTMLTransformer(null, $this->cacheDir); + $content = $transformer->transform($content); return strip_tags($content); } diff --git a/src/Oro/Bundle/NoteBundle/Provider/NoteActivityListProvider.php b/src/Oro/Bundle/NoteBundle/Provider/NoteActivityListProvider.php index 8303fa87d5f..1f218056129 100644 --- a/src/Oro/Bundle/NoteBundle/Provider/NoteActivityListProvider.php +++ b/src/Oro/Bundle/NoteBundle/Provider/NoteActivityListProvider.php @@ -68,8 +68,7 @@ public function getSubject($entity) } /** - * @param object $entity - * @return null + * {@inheritdoc} */ public function getDescription($entity) { From f5414d77bc0d5ab9d89541cbedb6e9c2aa5aeac9 Mon Sep 17 00:00:00 2001 From: Makar Sichevoy Date: Thu, 30 Apr 2015 15:55:13 +0300 Subject: [PATCH 04/47] CRM-2965: Add description field to ActivityListItem - update activity on body load --- .../EventListener/EmailBodyAddListener.php | 30 +++++++++++++++++-- .../EmailBundle/Resources/config/services.yml | 5 +++- .../EmailBodyAddListenerTest.php | 26 ++++++++++++---- 3 files changed, 53 insertions(+), 8 deletions(-) diff --git a/src/Oro/Bundle/EmailBundle/EventListener/EmailBodyAddListener.php b/src/Oro/Bundle/EmailBundle/EventListener/EmailBodyAddListener.php index 1ec413e6985..083b0dfe661 100644 --- a/src/Oro/Bundle/EmailBundle/EventListener/EmailBodyAddListener.php +++ b/src/Oro/Bundle/EmailBundle/EventListener/EmailBodyAddListener.php @@ -3,7 +3,9 @@ namespace Oro\Bundle\EmailBundle\EventListener; use Doctrine\Common\Util\ClassUtils; +use Doctrine\ORM\EntityManager; +use Oro\Bundle\ActivityListBundle\Provider\ActivityListChainProvider; use Oro\Bundle\AttachmentBundle\EntityConfig\AttachmentScope; use Oro\Bundle\EmailBundle\Event\EmailBodyAdded; use Oro\Bundle\EmailBundle\Manager\EmailAttachmentManager; @@ -28,28 +30,40 @@ class EmailBodyAddListener /** @var SecurityFacade */ protected $securityFacade; + /** @var ActivityListChainProvider */ + protected $chainProvider; + + /** @var EntityManager */ + protected $entityManager; + /** * @param EmailAttachmentManager $attachmentManager * @param ConfigProvider $configProvider * @param EmailActivityListProvider $activityListProvider * @param ServiceLink $securityFacadeLink + * @param ActivityListChainProvider $chainProvider + * @param EntityManager $entityManager */ public function __construct( EmailAttachmentManager $attachmentManager, ConfigProvider $configProvider, EmailActivityListProvider $activityListProvider, - ServiceLink $securityFacadeLink + ServiceLink $securityFacadeLink, + ActivityListChainProvider $chainProvider, + EntityManager $entityManager ) { $this->attachmentManager = $attachmentManager; $this->configProvider = $configProvider; $this->activityListProvider = $activityListProvider; $this->securityFacade = $securityFacadeLink->getService(); + $this->chainProvider = $chainProvider; + $this->entityManager = $entityManager; } /** * @param EmailBodyAdded $event */ - public function linkToScopeEvent(EmailBodyAdded $event) + public function linkToScope(EmailBodyAdded $event) { if ( $this->securityFacade->getToken() !== null @@ -67,4 +81,16 @@ public function linkToScopeEvent(EmailBodyAdded $event) } } } + + /** + * @param EmailBodyAdded $event + */ + public function updateActivityDescription(EmailBodyAdded $event) + { + $email = $event->getEmail(); + $activityList = $this->chainProvider->getUpdatedActivityList($email, $this->entityManager); + if ($activityList) { + $this->entityManager->persist($activityList); + } + } } diff --git a/src/Oro/Bundle/EmailBundle/Resources/config/services.yml b/src/Oro/Bundle/EmailBundle/Resources/config/services.yml index 454abdb6d87..729f1477457 100644 --- a/src/Oro/Bundle/EmailBundle/Resources/config/services.yml +++ b/src/Oro/Bundle/EmailBundle/Resources/config/services.yml @@ -522,8 +522,11 @@ services: - @oro_entity_config.provider.attachment - @oro_email.activity_list.provider - @oro_security.security_facade.link + - @oro_activity_list.provider.chain + - @doctrine.orm.entity_manager tags: - - { name: kernel.event_listener, event: oro_email.email_body_added, method: linkToScopeEvent, priority: 10 } + - { name: kernel.event_listener, event: oro_email.email_body_added, method: linkToScope, priority: 10 } + - { name: kernel.event_listener, event: oro_email.email_body_added, method: updateActivityDescription, priority: 20 } oro_email.provider.email_attachment_provider: class: %oro_email.provider.email_attachment_provider.class% diff --git a/src/Oro/Bundle/EmailBundle/Tests/Unit/EventListener/EmailBodyAddListenerTest.php b/src/Oro/Bundle/EmailBundle/Tests/Unit/EventListener/EmailBodyAddListenerTest.php index bb5f4c4c9f8..ebd224d5f56 100644 --- a/src/Oro/Bundle/EmailBundle/Tests/Unit/EventListener/EmailBodyAddListenerTest.php +++ b/src/Oro/Bundle/EmailBundle/Tests/Unit/EventListener/EmailBodyAddListenerTest.php @@ -2,6 +2,9 @@ namespace Oro\Bundle\EmailBundle\Tests\Unit\EventListener; +use Doctrine\ORM\EntityManager; + +use Oro\Bundle\ActivityListBundle\Provider\ActivityListChainProvider; use Oro\Bundle\EmailBundle\Tests\Unit\Fixtures\Entity\SomeEntity; use Oro\Bundle\EntityConfigBundle\Provider\ConfigProvider; use Oro\Bundle\EmailBundle\EventListener\EmailBodyAddListener; @@ -30,6 +33,12 @@ class EmailBodyAddListenerTest extends \PHPUnit_Framework_TestCase /** @var ServiceLink */ protected $securityFacadeLink; + /** @var ActivityListChainProvider */ + protected $chainProvider; + + /** @var EntityManager */ + protected $entityManager; + public function setUp() { $this->configProvider = $this->getMockBuilder('Oro\Bundle\EntityConfigBundle\Provider\ConfigProvider') @@ -46,16 +55,23 @@ public function setUp() $this->securityFacadeLink->expects($this->once()) ->method('getService') ->willReturn($this->securityFacade); + $this->chainProvider = + $this->getMockBuilder('Oro\Bundle\ActivityListBundle\Provider\ActivityListChainProvider') + ->disableOriginalConstructor()->getMock(); + $this->entityManager = $this->getMockBuilder('Doctrine\ORM\EntityManager') + ->disableOriginalConstructor()->getMock(); $this->listener = new EmailBodyAddListener( $this->emailAttachmentManager, $this->configProvider, $this->activityListProvider, - $this->securityFacadeLink + $this->securityFacadeLink, + $this->chainProvider, + $this->entityManager ); } - public function testLinkToScopeEventIsNotGranted() + public function testLinkToScopeIsNotGranted() { $event = $this->getMockBuilder('Oro\Bundle\EmailBundle\Event\EmailBodyAdded') ->disableOriginalConstructor()->getMock(); @@ -70,13 +86,13 @@ public function testLinkToScopeEventIsNotGranted() ->method('getTargetEntities') ->willReturn([new SomeEntity()]); - $this->listener->linkToScopeEvent($event); + $this->listener->linkToScope($event); } /** * @dataProvider getTestData */ - public function testLinkToScopeEvent($config, $managerCalls, $attachmentCalls) + public function testLinkToScope($config, $managerCalls, $attachmentCalls) { $attachments = $this->getMockBuilder('Oro\Bundle\EmailBundle\Entity\EmailAttachment') ->disableOriginalConstructor()->getMock(); @@ -120,7 +136,7 @@ public function testLinkToScopeEvent($config, $managerCalls, $attachmentCalls) ->method('getEmail') ->will($this->returnValue($email)); - $this->listener->linkToScopeEvent($event); + $this->listener->linkToScope($event); } public function getTestData() From 48b679bd5e4efc7bbe82171d1847e3526ed500ae Mon Sep 17 00:00:00 2001 From: Mykhailo Kudelia Date: Thu, 30 Apr 2015 17:28:58 +0300 Subject: [PATCH 05/47] CRM-2965: CR --- .../UpdateEmailActivityListDescription.php | 93 +++++++++++++++++++ .../Schema/OroActivityListBundleInstaller.php | 4 +- .../views/ActivityList/js/view.js.twig | 2 +- .../Bundle/EmailBundle/Tools/EmailHelper.php | 4 +- 4 files changed, 99 insertions(+), 4 deletions(-) create mode 100644 src/Oro/Bundle/ActivityListBundle/Migrations/Data/ORM/UpdateEmailActivityListDescription.php diff --git a/src/Oro/Bundle/ActivityListBundle/Migrations/Data/ORM/UpdateEmailActivityListDescription.php b/src/Oro/Bundle/ActivityListBundle/Migrations/Data/ORM/UpdateEmailActivityListDescription.php new file mode 100644 index 00000000000..212505355f0 --- /dev/null +++ b/src/Oro/Bundle/ActivityListBundle/Migrations/Data/ORM/UpdateEmailActivityListDescription.php @@ -0,0 +1,93 @@ +container = $container; + } + + /** + * {@inheritdoc} + */ + public function load(ObjectManager $manager) + { + $this->updateEmailActivityDescription($manager); + } + + /** + * Update activity + * @param ObjectManager $manager + */ + public function updateEmailActivityDescription(ObjectManager $manager) + { + $criteria = new Criteria(); + $criteria->where($criteria->expr()->eq('description', null)); + $criteria->where($criteria->expr()->eq('relatedActivityClass', Email::ENTITY_CLASS)); + /** @var QueryBuilder $activityListBuilder */ + $activityListBuilder = $manager->getRepository('OroActivityListBundle:ActivityList')->createQueryBuilder('e'); + $activityListBuilder->addCriteria($criteria); + + $iterator = new BufferedQueryResultIterator($activityListBuilder); + $iterator->setBufferSize(self::BATCH_SIZE); + + $itemsCount = 0; + $entities = []; + $emailRepository = $manager->getRepository('OroEmailBundle:Email'); + $activityProvider = $this->container->get('oro_email.activity_list.provider'); + + foreach ($iterator as $activity) { + + $email = $emailRepository->find($activity->getRelatedActivityId()); + + if ($email) { + $itemsCount++; + $activity->setDescription($activityProvider->getDescription($email)); + $entities[] = $activity; + } + + if (0 === $itemsCount % self::BATCH_SIZE) { + $this->saveEntities($manager, $entities); + $entities = []; + } + } + + if ($itemsCount % self::BATCH_SIZE > 0) { + $this->saveEntities($manager, $entities); + } + } + + /** + * @param ObjectManager $manager + * @param array $entities + */ + protected function saveEntities(ObjectManager $manager, array $entities) + { + foreach ($entities as $activity) { + $manager->persist($activity); + } + $manager->flush(); + $manager->clear(); + } +} diff --git a/src/Oro/Bundle/ActivityListBundle/Migrations/Schema/OroActivityListBundleInstaller.php b/src/Oro/Bundle/ActivityListBundle/Migrations/Schema/OroActivityListBundleInstaller.php index dfc4ed1df51..85e5d3a9afa 100644 --- a/src/Oro/Bundle/ActivityListBundle/Migrations/Schema/OroActivityListBundleInstaller.php +++ b/src/Oro/Bundle/ActivityListBundle/Migrations/Schema/OroActivityListBundleInstaller.php @@ -7,6 +7,7 @@ use Oro\Bundle\MigrationBundle\Migration\Installation; use Oro\Bundle\MigrationBundle\Migration\QueryBag; use Oro\Bundle\ActivityListBundle\Migrations\Schema\v1_1\OroActivityListBundle as OroActivityListBundle11; +use Oro\Bundle\ActivityListBundle\Migrations\Schema\v1_2\AddActivityDescription as AddActivityDescription12; class OroActivityListBundleInstaller implements Installation { @@ -15,7 +16,7 @@ class OroActivityListBundleInstaller implements Installation */ public function getMigrationVersion() { - return 'v1_1'; + return 'v1_2'; } /** @@ -30,6 +31,7 @@ public function up(Schema $schema, QueryBag $queries) $this->addOroActivityListForeignKeys($schema); OroActivityListBundle11::addColumns($schema); + AddActivityDescription12::addColumns($schema); } /** diff --git a/src/Oro/Bundle/ActivityListBundle/Resources/views/ActivityList/js/view.js.twig b/src/Oro/Bundle/ActivityListBundle/Resources/views/ActivityList/js/view.js.twig index e106d96e686..9fe262e57a7 100644 --- a/src/Oro/Bundle/ActivityListBundle/Resources/views/ActivityList/js/view.js.twig +++ b/src/Oro/Bundle/ActivityListBundle/Resources/views/ActivityList/js/view.js.twig @@ -27,7 +27,7 @@
{% block activityShortMessage %} <%= subject %> - <% if (description) { %> + <% if (!_.isUndefined(description) && !_.isEmpty(description)) { %> - <%= description %> <% } %> {% endblock %} diff --git a/src/Oro/Bundle/EmailBundle/Tools/EmailHelper.php b/src/Oro/Bundle/EmailBundle/Tools/EmailHelper.php index c9b65c361da..87392681b46 100644 --- a/src/Oro/Bundle/EmailBundle/Tools/EmailHelper.php +++ b/src/Oro/Bundle/EmailBundle/Tools/EmailHelper.php @@ -41,10 +41,10 @@ public function getStrippedBody($content) public function getOnlyLastAnswer(EmailBody $body) { if (!$body->getBodyIsText()) { - preg_match('/(.+)(
)/siU', $body->getBodyContent(), $match); + preg_match('/(.+)(
)/siU', $body->getBodyContent(), $match); if (isset($match[1])) { - return $match[1]; + return trim($match[1]); } } From 430cd01df1de572d4a6a2e5c5df3eb36e90affa6 Mon Sep 17 00:00:00 2001 From: Mykhailo Kudelia Date: Thu, 30 Apr 2015 18:01:01 +0300 Subject: [PATCH 06/47] CRM-2965: add test to email body listener --- .../EmailBodyAddListenerTest.php | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/Oro/Bundle/EmailBundle/Tests/Unit/EventListener/EmailBodyAddListenerTest.php b/src/Oro/Bundle/EmailBundle/Tests/Unit/EventListener/EmailBodyAddListenerTest.php index ebd224d5f56..88d5c9fd0cb 100644 --- a/src/Oro/Bundle/EmailBundle/Tests/Unit/EventListener/EmailBodyAddListenerTest.php +++ b/src/Oro/Bundle/EmailBundle/Tests/Unit/EventListener/EmailBodyAddListenerTest.php @@ -139,6 +139,33 @@ public function testLinkToScope($config, $managerCalls, $attachmentCalls) $this->listener->linkToScope($event); } + public function testUpdateActivityDescription() + { + $activityList = $this->getMockBuilder('Oro\Bundle\ActivityListBundle\Entity\ActivityList') + ->getMock(); + + $event = $this->getMockBuilder('Oro\Bundle\EmailBundle\Event\EmailBodyAdded') + ->disableOriginalConstructor()->getMock(); + + $email = $this->getMockBuilder('Oro\Bundle\EmailBundle\Entity\Email') + ->disableOriginalConstructor()->getMock(); + + $event->expects($this->exactly(1)) + ->method('getEmail') + ->will($this->returnValue($email)); + + $this->chainProvider->expects($this->exactly(1)) + ->method('getUpdatedActivityList') + ->with($this->identicalTo($email), $this->identicalTo($this->entityManager)) + ->will($this->returnValue($activityList)); + + $this->entityManager->expects($this->exactly(1)) + ->method('persist') + ->with($activityList); + + $this->listener->updateActivityDescription($event); + } + public function getTestData() { return [ From 73079a4ca5f6c3b9811bc65ada108ded8c6da738 Mon Sep 17 00:00:00 2001 From: Makar Sichevoy Date: Fri, 15 May 2015 18:24:44 +0300 Subject: [PATCH 07/47] CRM-2965: add description to activity list item --- .../Tests/Unit/Provider/ActivityListChainProviderTest.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Oro/Bundle/ActivityListBundle/Tests/Unit/Provider/ActivityListChainProviderTest.php b/src/Oro/Bundle/ActivityListBundle/Tests/Unit/Provider/ActivityListChainProviderTest.php index 01d62cdf1ca..cbf2324f9b7 100644 --- a/src/Oro/Bundle/ActivityListBundle/Tests/Unit/Provider/ActivityListChainProviderTest.php +++ b/src/Oro/Bundle/ActivityListBundle/Tests/Unit/Provider/ActivityListChainProviderTest.php @@ -85,14 +85,14 @@ public function testIsSupportedEntityWrongEntity() public function testGetSubject() { - $testEntity = new \stdClass(); + $testEntity = new \stdClass(); $testEntity->subject = 'test'; $this->assertEquals('test', $this->provider->getSubject($testEntity)); } public function testGetDescription() { - $testEntity = new \stdClass(); + $testEntity = new \stdClass(); $testEntity->description = 'test'; $this->assertEquals('test', $this->provider->getDescription($testEntity)); } @@ -105,7 +105,7 @@ public function testGetEmptySubject() public function testGetTargetEntityClasses() { - $correctTarget = new EntityConfigId('entity', 'Acme\\DemoBundle\\Entity\\CorrectEntity'); + $correctTarget = new EntityConfigId('entity', 'Acme\\DemoBundle\\Entity\\CorrectEntity'); $notCorrectTarget = new EntityConfigId('entity', 'Acme\\DemoBundle\\Entity\\NotCorrectEntity'); $this->configManager->expects($this->once()) ->method('getIds') @@ -135,7 +135,7 @@ public function testGetActivityListOption() { $entityConfigProvider = $this->getMockBuilder('Oro\Bundle\EntityConfigBundle\Provider\ConfigProvider') ->disableOriginalConstructor()->getMock(); - $configId = new EntityConfigId('entity', 'Test\Entity'); + $configId = new EntityConfigId('entity', 'Test\Entity'); $entityConfig = new Config($configId); $userConfig = $this->getMockBuilder('Oro\Bundle\ConfigBundle\Config\ConfigManager') ->disableOriginalConstructor()->getMock(); From 01f8af524fde5b87726e88fab5ae204d0d556678 Mon Sep 17 00:00:00 2001 From: Makar Sichevoy Date: Mon, 18 May 2015 16:14:52 +0300 Subject: [PATCH 08/47] CRM-2965: Add description to activity list item - translate --- .../Resources/translations/messages.en.yml | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/Oro/Bundle/ActivityListBundle/Resources/translations/messages.en.yml b/src/Oro/Bundle/ActivityListBundle/Resources/translations/messages.en.yml index 9fbfcb704b9..c459c56e85d 100644 --- a/src/Oro/Bundle/ActivityListBundle/Resources/translations/messages.en.yml +++ b/src/Oro/Bundle/ActivityListBundle/Resources/translations/messages.en.yml @@ -1,21 +1,22 @@ oro: activitylist: - entity_label: Activity list - entity_plural_label: Activity list - entity_description: Represent activities list + entity_label: Activity list + entity_plural_label: Activity list + entity_description: Represent activities list - id.label: Id - owner.label: Created by - editor.label: Updated by - verb.label: Verb - subject.label: Subject - data.label: Data - organization.label: Organization + id.label: Id + owner.label: Created by + editor.label: Updated by + verb.label: Verb + subject.label: Subject + data.label: Data + organization.label: Organization related_activity_class.label: Related activity class related_activity_id.label: Related activity id - created_at.label: Created at - updated_at.label: Updated at - head.label: Is Head + created_at.label: Created at + updated_at.label: Updated at + head.label: Is Head + description.label: Description no_activities_exist: No activities found @@ -25,7 +26,7 @@ oro: activity_list.label: Activity lists fields: sorting_field: - label: Sort by field + label: Sort by field choices: createdAt: Created date updatedAt: Updated date From 530a405eba28943a8e398f5947849b351ea336b6 Mon Sep 17 00:00:00 2001 From: Makar Sichevoy Date: Mon, 18 May 2015 16:19:19 +0300 Subject: [PATCH 09/47] CRM-2965: Add description to activity list item - CS fixes --- .../Migrations/Data/ORM/UpdateEmailActivityListDescription.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Oro/Bundle/ActivityListBundle/Migrations/Data/ORM/UpdateEmailActivityListDescription.php b/src/Oro/Bundle/ActivityListBundle/Migrations/Data/ORM/UpdateEmailActivityListDescription.php index 212505355f0..3b14d55589c 100644 --- a/src/Oro/Bundle/ActivityListBundle/Migrations/Data/ORM/UpdateEmailActivityListDescription.php +++ b/src/Oro/Bundle/ActivityListBundle/Migrations/Data/ORM/UpdateEmailActivityListDescription.php @@ -58,15 +58,12 @@ public function updateEmailActivityDescription(ObjectManager $manager) $activityProvider = $this->container->get('oro_email.activity_list.provider'); foreach ($iterator as $activity) { - $email = $emailRepository->find($activity->getRelatedActivityId()); - if ($email) { $itemsCount++; $activity->setDescription($activityProvider->getDescription($email)); $entities[] = $activity; } - if (0 === $itemsCount % self::BATCH_SIZE) { $this->saveEntities($manager, $entities); $entities = []; From 78b7213917fca18b7e9ea523643da105325d9d39 Mon Sep 17 00:00:00 2001 From: Makar Sichevoy Date: Mon, 18 May 2015 16:47:35 +0300 Subject: [PATCH 10/47] CRM-2965: Add description to activity list item - Entity field fix --- src/Oro/Bundle/ActivityListBundle/Entity/ActivityList.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Oro/Bundle/ActivityListBundle/Entity/ActivityList.php b/src/Oro/Bundle/ActivityListBundle/Entity/ActivityList.php index 076f795951e..0369640cf01 100644 --- a/src/Oro/Bundle/ActivityListBundle/Entity/ActivityList.php +++ b/src/Oro/Bundle/ActivityListBundle/Entity/ActivityList.php @@ -94,7 +94,7 @@ class ActivityList extends ExtendActivityList /** * @var string * - * @ORM\Column(name="description", type="text") + * @ORM\Column(name="description", type="text", nullable=true) * @Soap\ComplexType("string", nillable=true) */ protected $description; From b3fe134a67404ca035438e3c0e3f3fdb8960c15f Mon Sep 17 00:00:00 2001 From: Makar Sichevoy Date: Mon, 18 May 2015 17:19:13 +0300 Subject: [PATCH 11/47] CRM-2965: Add description to activity list item - Migration changes --- .../Migrations/Data/ORM/UpdateEmailActivityListDescription.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Oro/Bundle/ActivityListBundle/Migrations/Data/ORM/UpdateEmailActivityListDescription.php b/src/Oro/Bundle/ActivityListBundle/Migrations/Data/ORM/UpdateEmailActivityListDescription.php index 3b14d55589c..4b737917ce3 100644 --- a/src/Oro/Bundle/ActivityListBundle/Migrations/Data/ORM/UpdateEmailActivityListDescription.php +++ b/src/Oro/Bundle/ActivityListBundle/Migrations/Data/ORM/UpdateEmailActivityListDescription.php @@ -43,7 +43,6 @@ public function load(ObjectManager $manager) public function updateEmailActivityDescription(ObjectManager $manager) { $criteria = new Criteria(); - $criteria->where($criteria->expr()->eq('description', null)); $criteria->where($criteria->expr()->eq('relatedActivityClass', Email::ENTITY_CLASS)); /** @var QueryBuilder $activityListBuilder */ $activityListBuilder = $manager->getRepository('OroActivityListBundle:ActivityList')->createQueryBuilder('e'); From 1bef375e43cb3c19f5968c9faabcd408dfde2d31 Mon Sep 17 00:00:00 2001 From: Makar Sichevoy Date: Tue, 19 May 2015 12:24:31 +0300 Subject: [PATCH 12/47] CRM-2471: Add "Compose Email" button to My Emails - Fix CS --- .../Bundle/EmailBundle/Provider/EmailActivityListProvider.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Oro/Bundle/EmailBundle/Provider/EmailActivityListProvider.php b/src/Oro/Bundle/EmailBundle/Provider/EmailActivityListProvider.php index fe9d0825fcc..7fefa2d196e 100644 --- a/src/Oro/Bundle/EmailBundle/Provider/EmailActivityListProvider.php +++ b/src/Oro/Bundle/EmailBundle/Provider/EmailActivityListProvider.php @@ -125,7 +125,6 @@ public function getDescription($entity) { /** @var $entity Email */ if ($entity->getEmailBody()) { - $body = $entity->getEmailBody(); $content = $this->emailHelper->getOnlyLastAnswer($body); $content = $this->emailHelper->getStrippedBody($content); From 37b2282402d192235fa6cb0f190233e7c28b894b Mon Sep 17 00:00:00 2001 From: Makar Sichevoy Date: Tue, 19 May 2015 18:40:44 +0300 Subject: [PATCH 13/47] CRM-2965: Add description to activity list item - cr fixes --- .../UpdateEmailActivityListDescription.php | 3 -- .../CalendarEventActivityListProvider.php | 3 +- .../Provider/EmailActivityListProvider.php | 8 ++--- .../Tests/Unit/Tools/EmailHelperTest.php | 35 +++++++------------ .../Bundle/EmailBundle/Tools/EmailHelper.php | 26 ++------------ 5 files changed, 20 insertions(+), 55 deletions(-) diff --git a/src/Oro/Bundle/ActivityListBundle/Migrations/Data/ORM/UpdateEmailActivityListDescription.php b/src/Oro/Bundle/ActivityListBundle/Migrations/Data/ORM/UpdateEmailActivityListDescription.php index 4b737917ce3..1d1d8a3af3b 100644 --- a/src/Oro/Bundle/ActivityListBundle/Migrations/Data/ORM/UpdateEmailActivityListDescription.php +++ b/src/Oro/Bundle/ActivityListBundle/Migrations/Data/ORM/UpdateEmailActivityListDescription.php @@ -42,11 +42,8 @@ public function load(ObjectManager $manager) */ public function updateEmailActivityDescription(ObjectManager $manager) { - $criteria = new Criteria(); - $criteria->where($criteria->expr()->eq('relatedActivityClass', Email::ENTITY_CLASS)); /** @var QueryBuilder $activityListBuilder */ $activityListBuilder = $manager->getRepository('OroActivityListBundle:ActivityList')->createQueryBuilder('e'); - $activityListBuilder->addCriteria($criteria); $iterator = new BufferedQueryResultIterator($activityListBuilder); $iterator->setBufferSize(self::BATCH_SIZE); diff --git a/src/Oro/Bundle/CalendarBundle/Provider/CalendarEventActivityListProvider.php b/src/Oro/Bundle/CalendarBundle/Provider/CalendarEventActivityListProvider.php index 03f58d707c5..7486069f6fe 100644 --- a/src/Oro/Bundle/CalendarBundle/Provider/CalendarEventActivityListProvider.php +++ b/src/Oro/Bundle/CalendarBundle/Provider/CalendarEventActivityListProvider.php @@ -70,7 +70,8 @@ public function getSubject($entity) */ public function getDescription($entity) { - return null; + /** @var $entity CalendarEvent */ + return $entity->getDescription(); } /** diff --git a/src/Oro/Bundle/EmailBundle/Provider/EmailActivityListProvider.php b/src/Oro/Bundle/EmailBundle/Provider/EmailActivityListProvider.php index 7fefa2d196e..f94e422cd35 100644 --- a/src/Oro/Bundle/EmailBundle/Provider/EmailActivityListProvider.php +++ b/src/Oro/Bundle/EmailBundle/Provider/EmailActivityListProvider.php @@ -27,7 +27,6 @@ class EmailActivityListProvider implements CommentProviderInterface { const ACTIVITY_CLASS = 'Oro\Bundle\EmailBundle\Entity\Email'; - const MAX_DESCRIPTION_LENGTH = 80; /** @var DoctrineHelper */ protected $doctrineHelper; @@ -125,10 +124,9 @@ public function getDescription($entity) { /** @var $entity Email */ if ($entity->getEmailBody()) { - $body = $entity->getEmailBody(); - $content = $this->emailHelper->getOnlyLastAnswer($body); - $content = $this->emailHelper->getStrippedBody($content); - $content = $this->emailHelper->getShortBody($content, self::MAX_DESCRIPTION_LENGTH); + $body = $entity->getEmailBody()->getBodyContent(); + $content = $this->emailHelper->getStrippedBody($body); + $content = $this->emailHelper->getShortBody($content); return $content; } diff --git a/src/Oro/Bundle/EmailBundle/Tests/Unit/Tools/EmailHelperTest.php b/src/Oro/Bundle/EmailBundle/Tests/Unit/Tools/EmailHelperTest.php index 5acffe5343c..14c01006a9d 100644 --- a/src/Oro/Bundle/EmailBundle/Tests/Unit/Tools/EmailHelperTest.php +++ b/src/Oro/Bundle/EmailBundle/Tests/Unit/Tools/EmailHelperTest.php @@ -23,41 +23,30 @@ public function testGetStrippedBody() $this->assertEquals($expectedString, $this->helper->getStrippedBody($actualString)); } - /** - * @dataProvider bodiesProvider - */ - public function testGetOnlyLastAnswer($expected, $actual, $isTextContent) - { - $body = new EmailBody(); - $body->setBodyContent($actual); - $body->setBodyIsText($isTextContent); - - $this->assertEquals($expected, $this->helper->getOnlyLastAnswer($body)); - } - /** * @dataProvider shortBodiesProvider */ public function testGetShortBody($expected, $actual, $maxLength) { - $this->assertEquals($expected, $this->helper->getShortBody($actual, $maxLength)); + $shortBody = $this->helper->getShortBody($actual, $maxLength); + $this->assertEquals($expected, $shortBody); } public static function bodiesProvider() { - return array( - array('

Hello

', '

Hello

', false), - array('

Hello

', '

Hello

Other content
', false), - array('

H

H
', '

H

H
', true) - ); + return [ + ['

Hello

', '

Hello

', false], + ['

Hello

', '

Hello

Other content
', false], + ['

H

H
', '

H

H
', true] + ]; } public static function shortBodiesProvider() { - return array( - array('abc abc abc...', 'abc abc abc abc', 13), - array('abc abc abc abc', 'abc abc abc abc', 16), - array('abcabcabca...', 'abcabcabcabc', 10), - ); + return [ + ['abc abc abc', 'abc abc abc abc ', 12], + ['abc abc', 'abc abc abc abc abc', 8], + ['abcab', 'abcabcabcabc', 5], + ]; } } diff --git a/src/Oro/Bundle/EmailBundle/Tools/EmailHelper.php b/src/Oro/Bundle/EmailBundle/Tools/EmailHelper.php index 87392681b46..d1830df75cc 100644 --- a/src/Oro/Bundle/EmailBundle/Tools/EmailHelper.php +++ b/src/Oro/Bundle/EmailBundle/Tools/EmailHelper.php @@ -4,10 +4,10 @@ use Oro\Bundle\FormBundle\Form\DataTransformer\SanitizeHTMLTransformer; -use Oro\Bundle\EmailBundle\Entity\EmailBody; - class EmailHelper { + const MAX_DESCRIPTION_LENGTH = 500; + /** * @var string */ @@ -32,25 +32,6 @@ public function getStrippedBody($content) return strip_tags($content); } - /** - * If body is html, get content before first quote div, otherwise return body as it is - * - * @param EmailBody $body - * @return string - */ - public function getOnlyLastAnswer(EmailBody $body) - { - if (!$body->getBodyIsText()) { - preg_match('/(.+)(
)/siU', $body->getBodyContent(), $match); - - if (isset($match[1])) { - return trim($match[1]); - } - } - - return $body->getBodyContent(); - } - /** * Get shorter email body * @@ -58,7 +39,7 @@ public function getOnlyLastAnswer(EmailBody $body) * @param int $maxLength * @return string */ - public function getShortBody($content, $maxLength = 60) + public function getShortBody($content, $maxLength = self::MAX_DESCRIPTION_LENGTH) { if (mb_strlen($content) > $maxLength) { $content = mb_substr($content, 0, $maxLength); @@ -66,7 +47,6 @@ public function getShortBody($content, $maxLength = 60) if ($lastOccurrencePos !== false) { $content = mb_substr($content, 0, $lastOccurrencePos); } - $content .= '...'; } return $content; From b8c1ab779d6d405807809a72c3fb6c940e6eeeb1 Mon Sep 17 00:00:00 2001 From: Alexander Nezdoiminoga Date: Wed, 13 May 2015 17:43:31 +0300 Subject: [PATCH 14/47] CRM-3336: fix Tracking parse job blocks all other jobs --- .../Processor/TrackingProcessor.php | 58 ++++++++++++++++++- 1 file changed, 55 insertions(+), 3 deletions(-) diff --git a/src/Oro/Bundle/TrackingBundle/Processor/TrackingProcessor.php b/src/Oro/Bundle/TrackingBundle/Processor/TrackingProcessor.php index 8f4323e7595..de6e9acc97f 100644 --- a/src/Oro/Bundle/TrackingBundle/Processor/TrackingProcessor.php +++ b/src/Oro/Bundle/TrackingBundle/Processor/TrackingProcessor.php @@ -40,6 +40,9 @@ class TrackingProcessor implements LoggerAwareInterface /** Max retries to identify tracking visit */ const MAX_RETRIES = 100; + /** The maximum execution time (in minutes) */ + const MAX_EXEC_TIME_IN_MIN = 30; + /** @var ManagerRegistry */ protected $doctrine; @@ -61,6 +64,12 @@ class TrackingProcessor implements LoggerAwareInterface /** @var DeviceDetectorFactory */ protected $deviceDetector; + /** @var \DateTime start time */ + protected $startTime = null; + + /** @var \DateInterval|bool */ + protected $maxExecTimeout = false; + /** * @param ManagerRegistry $doctrine * @param TrackingEventIdentificationProvider $trackingIdentification @@ -70,6 +79,11 @@ public function __construct(ManagerRegistry $doctrine, TrackingEventIdentificati $this->doctrine = $doctrine; $this->trackingIdentification = $trackingIdentification; $this->deviceDetector = new DeviceDetectorFactory(); + + $this->startTime = $this->getCurrentUtcDateTime(); + $this->maxExecTimeout = self::MAX_EXEC_TIME_IN_MIN > 0 + ? new \DateInterval('PT' . self::MAX_EXEC_TIME_IN_MIN . 'M') + : false; } /** @@ -77,9 +91,7 @@ public function __construct(ManagerRegistry $doctrine, TrackingEventIdentificati */ public function process() { - /** - * To avoid memory leaks, we turn off doctrine logger - */ + /** To avoid memory leaks, we turn off doctrine logger */ $this->getEntityManager()->getConnection()->getConfiguration()->setSQLLogger(null); if ($this->logger === null) { @@ -107,23 +119,53 @@ public function process() date('Y-m-d H:i:s') ) ); + + if ($this->checkMaxExecutionTime()) { + return; + } } } $this->logger->notice('Recheck previous visit identifiers...'); while ($this->identifyPrevVisits()) { + if ($this->checkMaxExecutionTime()) { + return; + } + $this->logger->notice('Try to process Next batch'); } $this->logger->notice('Recheck previous visit events...'); $this->skipList = []; while ($this->identifyPrevVisitEvents()) { + if ($this->checkMaxExecutionTime()) { + return; + } + $this->logger->notice('Try to process Next batch'); } $this->logger->notice('Done'); } + /** + * Checks of process max execution time + * + * @return bool + */ + protected function checkMaxExecutionTime() + { + if ($this->maxExecTimeout !== false) { + $date = $this->getCurrentUtcDateTime(); + if ($date->sub($this->maxExecTimeout) >= $this->startTime) { + $this->logger->notice('Exit because allocated time frame elapsed.'); + return true; + } + } + + return false; + } + /** * Returns count of web events to be processed. * @@ -571,4 +613,14 @@ protected function getEntityManager() return $em; } + + /** + * Gets a DateTime object that is set to the current date and time in UTC. + * + * @return \DateTime + */ + protected function getCurrentUtcDateTime() + { + return new \DateTime('now', new \DateTimeZone('UTC')); + } } From 9186c717a492ee07ebc1c9fdefb4501ab2645359 Mon Sep 17 00:00:00 2001 From: dmitrosh Date: Thu, 21 May 2015 16:01:57 +0300 Subject: [PATCH 15/47] OEE-583: Quick Launchpad is lost on Organization start page --- .../Resources/views/Dashboard/launchpad.html.twig | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/Oro/Bundle/DashboardBundle/Resources/views/Dashboard/launchpad.html.twig b/src/Oro/Bundle/DashboardBundle/Resources/views/Dashboard/launchpad.html.twig index 6ea82c7d147..f65c3bcafc2 100644 --- a/src/Oro/Bundle/DashboardBundle/Resources/views/Dashboard/launchpad.html.twig +++ b/src/Oro/Bundle/DashboardBundle/Resources/views/Dashboard/launchpad.html.twig @@ -1,10 +1,5 @@ -{% extends 'OroDashboardBundle:Dashboard:widget.html.twig' %} - -{% set widgetType = 'launchpad' %} -{% set widgetTitle = false %} - -{% block content %} - {% if widgetAcl is defined and resource_granted(widgetAcl) %} +{% if widgetAcl is defined and resource_granted(widgetAcl) %} +

@@ -26,7 +21,5 @@

- {% endif %} -{% endblock %} - -{% block actions %}{% endblock %} +
+{% endif %} From 809a54af8dda8f14aa9c04b914b86953b74f6ce7 Mon Sep 17 00:00:00 2001 From: dmitrosh Date: Fri, 22 May 2015 15:55:53 +0300 Subject: [PATCH 16/47] BAP-8081: improve performance on Firefox --- .../public/js/app/plugins/grid/floating-header-plugin.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Oro/Bundle/DataGridBundle/Resources/public/js/app/plugins/grid/floating-header-plugin.js b/src/Oro/Bundle/DataGridBundle/Resources/public/js/app/plugins/grid/floating-header-plugin.js index 2046a8e4a73..c77c1cfd062 100644 --- a/src/Oro/Bundle/DataGridBundle/Resources/public/js/app/plugins/grid/floating-header-plugin.js +++ b/src/Oro/Bundle/DataGridBundle/Resources/public/js/app/plugins/grid/floating-header-plugin.js @@ -302,7 +302,12 @@ define(function (require) { }); }); scrollStateModel.on('change:scrollTop', function (model, val) { - otherScroll[0].scrollTop = scrollContainer[0].scrollTop = val; + if (otherScroll[0].scrollTop !== val) { + otherScroll[0].scrollTop = val; + } + if (scrollContainer[0].scrollTop !== val) { + scrollContainer[0].scrollTop = val; + } }, this); function updateScroll(e) { From 76daad7b4fd7d003fbf4df3db4661efff6071c5b Mon Sep 17 00:00:00 2001 From: dmitrosh Date: Fri, 22 May 2015 19:35:02 +0300 Subject: [PATCH 17/47] OEE-583: add condition to template --- .../Resources/views/Dashboard/launchpad.html.twig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Oro/Bundle/DashboardBundle/Resources/views/Dashboard/launchpad.html.twig b/src/Oro/Bundle/DashboardBundle/Resources/views/Dashboard/launchpad.html.twig index f65c3bcafc2..aa2b3f673af 100644 --- a/src/Oro/Bundle/DashboardBundle/Resources/views/Dashboard/launchpad.html.twig +++ b/src/Oro/Bundle/DashboardBundle/Resources/views/Dashboard/launchpad.html.twig @@ -1,5 +1,5 @@ {% if widgetAcl is defined and resource_granted(widgetAcl) %} -
+

From 40ae5467926bc4d614eb18a2bbd4395c0fd68982 Mon Sep 17 00:00:00 2001 From: Pavel Romanenko Date: Tue, 19 May 2015 12:58:09 +0300 Subject: [PATCH 18/47] CRM-3373: Can't export Lead - modified ExtendExtension and EnumEntityConfigDumperExtension to change enum identity from name to id - fixed test --- .../Migration/Extension/ExtendExtension.php | 7 +++---- .../Unit/Migration/Extension/ExtendExtensionTest.php | 12 ++++++------ .../EnumEntityConfigDumperExtensionTest.php | 6 +++--- .../EnumEntityConfigDumperExtension.php | 6 +++--- 4 files changed, 15 insertions(+), 16 deletions(-) diff --git a/src/Oro/Bundle/EntityExtendBundle/Migration/Extension/ExtendExtension.php b/src/Oro/Bundle/EntityExtendBundle/Migration/Extension/ExtendExtension.php index 34652889012..cac8340cbf8 100644 --- a/src/Oro/Bundle/EntityExtendBundle/Migration/Extension/ExtendExtension.php +++ b/src/Oro/Bundle/EntityExtendBundle/Migration/Extension/ExtendExtension.php @@ -191,6 +191,9 @@ public function createEnum( 'entity' => [ 'label' => ExtendHelper::getEnumTranslationKey('label', $enumCode, 'id'), 'description' => ExtendHelper::getEnumTranslationKey('description', $enumCode, 'id') + ], + 'importexport' => [ + 'identity' => true ] ] ] @@ -207,11 +210,7 @@ public function createEnum( ], 'datagrid' => [ 'is_visible' => false - ], - 'importexport' => [ - 'identity' => true ] - ] ] ); diff --git a/src/Oro/Bundle/EntityExtendBundle/Tests/Unit/Migration/Extension/ExtendExtensionTest.php b/src/Oro/Bundle/EntityExtendBundle/Tests/Unit/Migration/Extension/ExtendExtensionTest.php index 0160406e79c..abb067d3ba9 100644 --- a/src/Oro/Bundle/EntityExtendBundle/Tests/Unit/Migration/Extension/ExtendExtensionTest.php +++ b/src/Oro/Bundle/EntityExtendBundle/Tests/Unit/Migration/Extension/ExtendExtensionTest.php @@ -352,7 +352,8 @@ public function testCreateEnum() 'entity' => [ 'label' => 'oro.entityextend.enumvalue.id.label', 'description' => 'oro.entityextend.enumvalue.id.description', - ] + ], + 'importexport' => ['identity' => true] ], 'type' => 'string' ], @@ -362,8 +363,7 @@ public function testCreateEnum() 'label' => 'oro.entityextend.enumvalue.name.label', 'description' => 'oro.entityextend.enumvalue.name.description', ], - 'datagrid' => ['is_visible' => false], - 'importexport' => ['identity' => true] + 'datagrid' => ['is_visible' => false] ], 'type' => 'string' ], @@ -465,6 +465,9 @@ public function testCreateImmutableEnum() 'entity' => [ 'label' => 'oro.entityextend.enumvalue.id.label', 'description' => 'oro.entityextend.enumvalue.id.description', + ], + 'importexport' => [ + 'identity' => true ] ], 'type' => 'string', @@ -477,9 +480,6 @@ public function testCreateImmutableEnum() ], 'datagrid' => [ 'is_visible' => false - ], - 'importexport' => [ - 'identity' => true ] ], 'type' => 'string', diff --git a/src/Oro/Bundle/EntityExtendBundle/Tests/Unit/Tools/DumperExtensions/EnumEntityConfigDumperExtensionTest.php b/src/Oro/Bundle/EntityExtendBundle/Tests/Unit/Tools/DumperExtensions/EnumEntityConfigDumperExtensionTest.php index 0663fc9fcab..a0d8eab1cba 100644 --- a/src/Oro/Bundle/EntityExtendBundle/Tests/Unit/Tools/DumperExtensions/EnumEntityConfigDumperExtensionTest.php +++ b/src/Oro/Bundle/EntityExtendBundle/Tests/Unit/Tools/DumperExtensions/EnumEntityConfigDumperExtensionTest.php @@ -385,6 +385,9 @@ protected function setAddEnumValueEntityFieldsExpectations( 'entity' => [ 'label' => ExtendHelper::getEnumTranslationKey('label', $enumCode, 'id'), 'description' => ExtendHelper::getEnumTranslationKey('description', $enumCode, 'id') + ], + 'importexport' => [ + 'identity' => true ] ] ); @@ -400,9 +403,6 @@ protected function setAddEnumValueEntityFieldsExpectations( ], 'datagrid' => [ 'is_visible' => false - ], - 'importexport' => [ - 'identity' => true ] ] ); diff --git a/src/Oro/Bundle/EntityExtendBundle/Tools/DumperExtensions/EnumEntityConfigDumperExtension.php b/src/Oro/Bundle/EntityExtendBundle/Tools/DumperExtensions/EnumEntityConfigDumperExtension.php index d1040780d6b..77868cd5f00 100644 --- a/src/Oro/Bundle/EntityExtendBundle/Tools/DumperExtensions/EnumEntityConfigDumperExtension.php +++ b/src/Oro/Bundle/EntityExtendBundle/Tools/DumperExtensions/EnumEntityConfigDumperExtension.php @@ -271,7 +271,8 @@ protected function createEnumValueConfigEntityModel($enumValueClassName, $enumCo 'entity' => [ 'label' => ExtendHelper::getEnumTranslationKey('label', $enumCode, 'id'), 'description' => ExtendHelper::getEnumTranslationKey('description', $enumCode, 'id') - ] + ], + 'importexport' => ['identity' => true] ] ); $this->configManager->createConfigFieldModel($enumValueClassName, 'name', 'string'); @@ -283,8 +284,7 @@ protected function createEnumValueConfigEntityModel($enumValueClassName, $enumCo 'label' => ExtendHelper::getEnumTranslationKey('label', $enumCode, 'name'), 'description' => ExtendHelper::getEnumTranslationKey('description', $enumCode, 'name') ], - 'datagrid' => ['is_visible' => false], - 'importexport' => ['identity' => true] + 'datagrid' => ['is_visible' => false] ] ); $this->configManager->createConfigFieldModel($enumValueClassName, 'priority', 'integer'); From b1541d12801e99767bb7e162dc6bef328152707e Mon Sep 17 00:00:00 2001 From: Pavel Romanenko Date: Mon, 25 May 2015 18:28:11 +0300 Subject: [PATCH 19/47] CRM-3373: Can't export Lead - CR fix, added migration --- .../Schema/v1_3/ChangeEnumIdentityQuery.php | 149 ++++++++++++++++++ .../Schema/v1_3/OroEntityExtendBundle.php | 21 +++ 2 files changed, 170 insertions(+) create mode 100644 src/Oro/Bundle/EntityExtendBundle/Migrations/Schema/v1_3/ChangeEnumIdentityQuery.php create mode 100644 src/Oro/Bundle/EntityExtendBundle/Migrations/Schema/v1_3/OroEntityExtendBundle.php diff --git a/src/Oro/Bundle/EntityExtendBundle/Migrations/Schema/v1_3/ChangeEnumIdentityQuery.php b/src/Oro/Bundle/EntityExtendBundle/Migrations/Schema/v1_3/ChangeEnumIdentityQuery.php new file mode 100644 index 00000000000..ed94e2801f1 --- /dev/null +++ b/src/Oro/Bundle/EntityExtendBundle/Migrations/Schema/v1_3/ChangeEnumIdentityQuery.php @@ -0,0 +1,149 @@ +doExecute($logger, true); + + return $logger->getMessages(); + } + + /** + * {@inheritdoc} + */ + public function execute(LoggerInterface $logger) + { + $this->doExecute($logger); + } + + /** + * @param LoggerInterface $logger + * @param bool $dryRun + */ + protected function doExecute(LoggerInterface $logger, $dryRun = false) + { + $enumEntityIds = $this->getEnumEntityIds($logger); + + if (empty($enumEntityIds)) { + return; + } + + $enumEntities = $this->getEnumEntitiesWithFields($logger, $enumEntityIds); + + $this->processChange($logger, $enumEntities, $dryRun); + } + + /** + * @param LoggerInterface $logger + * + * @return array + */ + protected function getEnumEntityIds(LoggerInterface $logger) + { + $sql = 'SELECT id, data FROM oro_entity_config'; + $this->logQuery($logger, $sql); + + $rows = $this->connection->fetchAll($sql); + + $entities = []; + + foreach ($rows as $row) { + $data = $this->connection->convertToPHPValue($row['data'], 'array'); + + if (array_key_exists('extend', $data) + && array_key_exists('inherit', $data['extend']) + && $data['extend']['inherit'] == 'Oro\Bundle\EntityExtendBundle\Entity\AbstractEnumValue' + ) { + $entities[] = $row['id']; + } + } + + return $entities; + } + + /** + * @param LoggerInterface $logger + * @param array $entityIds + * + * @return array + */ + protected function getEnumEntitiesWithFields(LoggerInterface $logger, array $entityIds) + { + $sql = 'SELECT fc.id, fc.entity_id, fc.field_name, fc.data FROM oro_entity_config ec ' + . 'INNER JOIN oro_entity_config_field fc ON fc.entity_id = ec.id AND ec.id IN (' + . implode(', ', $entityIds) + . ') WHERE fc.field_name IN (:field_from, :field_to)'; + $params = ['field_from' => self::FIELD_FROM, 'field_to' => self::FIELD_TO]; + + $this->logQuery($logger, $sql, $params); + + $rows = $this->connection->fetchAll($sql, $params); + + $entities = []; + + foreach ($rows as $row) { + $entities[$row['entity_id']][$row['field_name']] = [ + 'id' => $row['id'], + 'entity_id' => $row['entity_id'], + 'field_name' => $row['field_name'], + 'data' => $this->connection->convertToPHPValue($row['data'], 'array') + ]; + } + + return $entities; + } + + /** + * @param LoggerInterface $logger + * @param array $entities + * @param bool $dryRun + */ + protected function processChange(LoggerInterface $logger, array $entities, $dryRun = false) + { + foreach ($entities as $enumEntity) { + if (array_key_exists(self::FIELD_FROM, $enumEntity) + && array_key_exists('data', $enumEntity[self::FIELD_FROM]) + && array_key_exists('importexport', $enumEntity[self::FIELD_FROM]['data']) + && array_key_exists('identity', $enumEntity[self::FIELD_FROM]['data']['importexport']) + && array_key_exists(self::FIELD_TO, $enumEntity) + && array_key_exists('data', $enumEntity[self::FIELD_TO]) + ) { + // remove identity + unset($enumEntity[self::FIELD_FROM]['data']['importexport']['identity']); + + // add identity + $enumEntity[self::FIELD_TO]['data']['importexport']['identity'] = true; + + $sql = 'UPDATE oro_entity_config_field SET data = :data WHERE id = :id'; + + foreach ($enumEntity as $enumEntityField) { + $params = ['data' => $enumEntityField['data'], 'id' => $enumEntityField['id']]; + $types = ['data' => 'array', 'id' => 'integer']; + + $this->logQuery($logger, $sql, $params, $types); + + if (!$dryRun) { + $this->connection->executeUpdate($sql, $params, $types); + } + } + } + } + } +} diff --git a/src/Oro/Bundle/EntityExtendBundle/Migrations/Schema/v1_3/OroEntityExtendBundle.php b/src/Oro/Bundle/EntityExtendBundle/Migrations/Schema/v1_3/OroEntityExtendBundle.php new file mode 100644 index 00000000000..ae231696643 --- /dev/null +++ b/src/Oro/Bundle/EntityExtendBundle/Migrations/Schema/v1_3/OroEntityExtendBundle.php @@ -0,0 +1,21 @@ +addPostQuery( + new ChangeEnumIdentityQuery() + ); + } +} From 10b16df8e3abe944daa59c40640b330070ae9c0d Mon Sep 17 00:00:00 2001 From: Makar Sichevoy Date: Tue, 26 May 2015 16:16:32 +0300 Subject: [PATCH 20/47] CRM-2965: Add description field to ActivityListItem - merge --- .../Provider/EmailActivityListProvider.php | 18 ++--- .../EmailBundle/Resources/config/services.yml | 9 +-- .../Bundle/EmailBundle/Tools/EmailHelper.php | 54 --------------- .../UIBundle/Resources/config/services.yml | 8 +++ .../Bundle/UIBundle/Resources/config/twig.yml | 3 +- .../Tests/Unit/Tools/HtmlTagHelperTest.php} | 20 +++--- .../Tests/Unit/Twig/HtmlTagExtensionTest.php | 10 +-- .../Bundle/UIBundle/Tools/HtmlTagHelper.php | 69 +++++++++++++++++++ .../Bundle/UIBundle/Twig/HtmlTagExtension.php | 28 +++----- 9 files changed, 117 insertions(+), 102 deletions(-) delete mode 100644 src/Oro/Bundle/EmailBundle/Tools/EmailHelper.php rename src/Oro/Bundle/{EmailBundle/Tests/Unit/Tools/EmailHelperTest.php => UIBundle/Tests/Unit/Tools/HtmlTagHelperTest.php} (64%) create mode 100644 src/Oro/Bundle/UIBundle/Tools/HtmlTagHelper.php diff --git a/src/Oro/Bundle/EmailBundle/Provider/EmailActivityListProvider.php b/src/Oro/Bundle/EmailBundle/Provider/EmailActivityListProvider.php index f94e422cd35..e7d28972f0e 100644 --- a/src/Oro/Bundle/EmailBundle/Provider/EmailActivityListProvider.php +++ b/src/Oro/Bundle/EmailBundle/Provider/EmailActivityListProvider.php @@ -18,7 +18,7 @@ use Oro\Bundle\EntityConfigBundle\Config\Id\ConfigIdInterface; use Oro\Bundle\EntityConfigBundle\DependencyInjection\Utils\ServiceLink; use Oro\Bundle\CommentBundle\Model\CommentProviderInterface; -use Oro\Bundle\EmailBundle\Tools\EmailHelper; +use Oro\Bundle\UIBundle\Tools\HtmlTagHelper; class EmailActivityListProvider implements ActivityListProviderInterface, @@ -46,10 +46,8 @@ class EmailActivityListProvider implements /** @var EmailThreadProvider */ protected $emailThreadProvider; - /** - * @var EmailHelper - */ - protected $emailHelper; + /** @var HtmlTagHelper */ + protected $htmlTagHelper; /** * @param DoctrineHelper $doctrineHelper @@ -58,6 +56,7 @@ class EmailActivityListProvider implements * @param Router $router * @param ConfigManager $configManager * @param EmailThreadProvider $emailThreadProvider + * @param HtmlTagHelper $htmlTagHelper */ public function __construct( DoctrineHelper $doctrineHelper, @@ -66,7 +65,7 @@ public function __construct( Router $router, ConfigManager $configManager, EmailThreadProvider $emailThreadProvider, - EmailHelper $emailHelper + HtmlTagHelper $htmlTagHelper ) { $this->doctrineHelper = $doctrineHelper; $this->doctrineRegistryLink = $doctrineRegistryLink; @@ -74,7 +73,7 @@ public function __construct( $this->router = $router; $this->configManager = $configManager; $this->emailThreadProvider = $emailThreadProvider; - $this->emailHelper = $emailHelper; + $this->htmlTagHelper = $htmlTagHelper; } /** @@ -125,8 +124,9 @@ public function getDescription($entity) /** @var $entity Email */ if ($entity->getEmailBody()) { $body = $entity->getEmailBody()->getBodyContent(); - $content = $this->emailHelper->getStrippedBody($body); - $content = $this->emailHelper->getShortBody($content); + $content = $this->htmlTagHelper->getPurify($body); + $content = $this->htmlTagHelper->getStripped($content); + $content = $this->htmlTagHelper->getShort($content); return $content; } diff --git a/src/Oro/Bundle/EmailBundle/Resources/config/services.yml b/src/Oro/Bundle/EmailBundle/Resources/config/services.yml index 729f1477457..3098871fa74 100644 --- a/src/Oro/Bundle/EmailBundle/Resources/config/services.yml +++ b/src/Oro/Bundle/EmailBundle/Resources/config/services.yml @@ -4,7 +4,7 @@ parameters: oro_email.email_folder.model.class: Oro\Bundle\EmailBundle\Model\FolderType oro_email.email.cache.manager.class: Oro\Bundle\EmailBundle\Cache\EmailCacheManager oro_email.email_holder_helper.class: Oro\Bundle\EmailBundle\Tools\EmailHolderHelper - oro_email.email_helper.class: Oro\Bundle\EmailBundle\Tools\EmailHelper +# oro_email.email_helper.class: Oro\Bundle\EmailBundle\Tools\EmailHelper oro_email.email.address.helper.class: Oro\Bundle\EmailBundle\Tools\EmailAddressHelper oro_email.email.address.manager.class: Oro\Bundle\EmailBundle\Entity\Manager\EmailAddressManager oro_email.email.owner.provider.class: Oro\Bundle\EmailBundle\Entity\Provider\EmailOwnerProvider @@ -115,11 +115,6 @@ services: arguments: - @oro_entity_config.provider.extend - oro_email.email_helper: - class: %oro_email.email_helper.class% - arguments: - - %kernel.cache_dir% - oro_email.email.address.helper: class: %oro_email.email.address.helper.class% @@ -497,7 +492,7 @@ services: - @router - @oro_entity_config.config_manager - @oro_email.email.thread.provider - - @oro_email.email_helper + - @oro_ui.html_tag_helper tags: - {name: oro_activity_list.provider, priority: 30} diff --git a/src/Oro/Bundle/EmailBundle/Tools/EmailHelper.php b/src/Oro/Bundle/EmailBundle/Tools/EmailHelper.php deleted file mode 100644 index d1830df75cc..00000000000 --- a/src/Oro/Bundle/EmailBundle/Tools/EmailHelper.php +++ /dev/null @@ -1,54 +0,0 @@ -cacheDir = $cacheDir; - } - - /** - * @param string $content - * @return string - */ - public function getStrippedBody($content) - { - $transformer = new SanitizeHTMLTransformer(null, $this->cacheDir); - $content = $transformer->transform($content); - return strip_tags($content); - } - - /** - * Get shorter email body - * - * @param string $content - * @param int $maxLength - * @return string - */ - public function getShortBody($content, $maxLength = self::MAX_DESCRIPTION_LENGTH) - { - if (mb_strlen($content) > $maxLength) { - $content = mb_substr($content, 0, $maxLength); - $lastOccurrencePos = strrpos($content, ' '); - if ($lastOccurrencePos !== false) { - $content = mb_substr($content, 0, $lastOccurrencePos); - } - } - - return $content; - } -} diff --git a/src/Oro/Bundle/UIBundle/Resources/config/services.yml b/src/Oro/Bundle/UIBundle/Resources/config/services.yml index 8d30bfdcace..74916b4eaca 100644 --- a/src/Oro/Bundle/UIBundle/Resources/config/services.yml +++ b/src/Oro/Bundle/UIBundle/Resources/config/services.yml @@ -17,6 +17,8 @@ parameters: oro_ui.view.content_provider.listener.class: Oro\Bundle\UIBundle\EventListener\ContentProviderListener + oro_ui.html_tag_helper.class: Oro\Bundle\UIBundle\Tools\HtmlTagHelper + services: # Placeholder services oro_ui.placeholder.provider: @@ -214,3 +216,9 @@ services: public: false tags: - { name: layout.resource.path_provider, priority: -10 } + + oro_ui.html_tag_helper: + class: %oro_ui.html_tag_helper.class% + arguments: + - @oro_form.provider.html_tag_provider + - %kernel.cache_dir% diff --git a/src/Oro/Bundle/UIBundle/Resources/config/twig.yml b/src/Oro/Bundle/UIBundle/Resources/config/twig.yml index ccca3e01d0a..527fdd36379 100644 --- a/src/Oro/Bundle/UIBundle/Resources/config/twig.yml +++ b/src/Oro/Bundle/UIBundle/Resources/config/twig.yml @@ -138,7 +138,6 @@ services: oro_ui.twig.html_tag: class: %oro_ui.twig.html_tag.class% arguments: - - @oro_form.provider.html_tag_provider - - %kernel.cache_dir% + - @oro_ui.html_tag_helper tags: - { name: twig.extension } diff --git a/src/Oro/Bundle/EmailBundle/Tests/Unit/Tools/EmailHelperTest.php b/src/Oro/Bundle/UIBundle/Tests/Unit/Tools/HtmlTagHelperTest.php similarity index 64% rename from src/Oro/Bundle/EmailBundle/Tests/Unit/Tools/EmailHelperTest.php rename to src/Oro/Bundle/UIBundle/Tests/Unit/Tools/HtmlTagHelperTest.php index 14c01006a9d..a02b8f0a5c9 100644 --- a/src/Oro/Bundle/EmailBundle/Tests/Unit/Tools/EmailHelperTest.php +++ b/src/Oro/Bundle/UIBundle/Tests/Unit/Tools/HtmlTagHelperTest.php @@ -1,18 +1,22 @@ helper = new EmailHelper(); + $this->htmlTagProvider = $this->getMock('Oro\Bundle\FormBundle\Provider\HtmlTagProvider'); + $this->helper = new HtmlTagHelper($this->htmlTagProvider); } public function testGetStrippedBody() @@ -20,7 +24,7 @@ public function testGetStrippedBody() $actualString = '

test
'; $expectedString = 'test'; - $this->assertEquals($expectedString, $this->helper->getStrippedBody($actualString)); + $this->assertEquals($expectedString, $this->helper->getStripped($actualString)); } /** @@ -28,7 +32,7 @@ public function testGetStrippedBody() */ public function testGetShortBody($expected, $actual, $maxLength) { - $shortBody = $this->helper->getShortBody($actual, $maxLength); + $shortBody = $this->helper->getShort($actual, $maxLength); $this->assertEquals($expected, $shortBody); } diff --git a/src/Oro/Bundle/UIBundle/Tests/Unit/Twig/HtmlTagExtensionTest.php b/src/Oro/Bundle/UIBundle/Tests/Unit/Twig/HtmlTagExtensionTest.php index 8ae1fd71830..4ae5bd99523 100644 --- a/src/Oro/Bundle/UIBundle/Tests/Unit/Twig/HtmlTagExtensionTest.php +++ b/src/Oro/Bundle/UIBundle/Tests/Unit/Twig/HtmlTagExtensionTest.php @@ -2,7 +2,7 @@ namespace Oro\Bundle\UIBundle\Tests\Unit\Twig; -use Oro\Bundle\FormBundle\Provider\HtmlTagProvider; +use Oro\Bundle\UIBundle\Tools\HtmlTagHelper; use Oro\Bundle\UIBundle\Twig\HtmlTagExtension; class HtmlTagExtensionTest extends \PHPUnit_Framework_TestCase @@ -13,15 +13,15 @@ class HtmlTagExtensionTest extends \PHPUnit_Framework_TestCase protected $extension; /** - * @var HtmlTagProvider|\PHPUnit_Framework_MockObject_MockObject + * @var HtmlTagHelper|\PHPUnit_Framework_MockObject_MockObject */ - protected $htmlTagProvider; + protected $htmlTagHelper; protected function setUp() { - $this->htmlTagProvider = $this->getMock('Oro\Bundle\FormBundle\Provider\HtmlTagProvider'); + $this->htmlTagHelper = $this->getMock('Oro\Bundle\FormBundle\Provider\HtmlTagHelper'); - $this->extension = new HtmlTagExtension($this->htmlTagProvider); + $this->extension = new HtmlTagExtension($this->htmlTagHelper); } public function testGetName() diff --git a/src/Oro/Bundle/UIBundle/Tools/HtmlTagHelper.php b/src/Oro/Bundle/UIBundle/Tools/HtmlTagHelper.php new file mode 100644 index 00000000000..d0c740e1c23 --- /dev/null +++ b/src/Oro/Bundle/UIBundle/Tools/HtmlTagHelper.php @@ -0,0 +1,69 @@ +htmlTagProvider = $htmlTagProvider; + $this->cacheDir = $cacheDir; + } + + /** + * @param string $string + * @return string + */ + public function getPurify($string) + { + $transformer = new SanitizeHTMLTransformer(null, $this->cacheDir); + return $transformer->transform($string); + } + + /** + * @param string $string + * @param bool $uiAllowedTags + * @return string + */ + public function getStripped($string, $uiAllowedTags = false) + { + if ($uiAllowedTags) { + return strip_tags($string, $this->htmlTagProvider->getAllowedTags()); + } + return strip_tags($string); + } + + /** + * Get shorter text + * + * @param string $string + * @param int $maxLength + * @return string + */ + public function getShort($string, $maxLength = self::MAX_STRING_LENGTH) + { + if (mb_strlen($string) > $maxLength) { + $string = mb_substr($string, 0, $maxLength); + $lastOccurrencePos = strrpos($string, ' '); + if ($lastOccurrencePos !== false) { + $string = mb_substr($string, 0, $lastOccurrencePos); + } + } + + return $string; + } +} diff --git a/src/Oro/Bundle/UIBundle/Twig/HtmlTagExtension.php b/src/Oro/Bundle/UIBundle/Twig/HtmlTagExtension.php index 49255ac42cf..e49881c6141 100644 --- a/src/Oro/Bundle/UIBundle/Twig/HtmlTagExtension.php +++ b/src/Oro/Bundle/UIBundle/Twig/HtmlTagExtension.php @@ -2,29 +2,24 @@ namespace Oro\Bundle\UIBundle\Twig; -use Oro\Bundle\FormBundle\Form\DataTransformer\SanitizeHTMLTransformer; use Oro\Bundle\FormBundle\Provider\HtmlTagProvider; +use Oro\Bundle\UIBundle\Tools\HtmlTagHelper; class HtmlTagExtension extends \Twig_Extension { - /** - * @var HtmlTagProvider - */ + /** @var HtmlTagProvider */ protected $htmlTagProvider; - /** - * @var string - */ - protected $cacheDir; + /** @var HtmlTagHelper */ + protected $htmlTagHelper; /** - * @param HtmlTagProvider $htmlTagProvider - * @param string $cacheDir + * @param HtmlTagHelper $htmlTagHelper */ - public function __construct(HtmlTagProvider $htmlTagProvider, $cacheDir = null) - { - $this->htmlTagProvider = $htmlTagProvider; - $this->cacheDir = $cacheDir; + public function __construct( + HtmlTagHelper $htmlTagHelper + ) { + $this->htmlTagHelper = $htmlTagHelper; } /** @@ -45,7 +40,7 @@ public function getFilters() */ public function tagFilter($string) { - return strip_tags($string, $this->htmlTagProvider->getAllowedTags()); + return $this->htmlTagHelper->getStripped($string); } /** @@ -56,8 +51,7 @@ public function tagFilter($string) */ public function htmlPurify($string) { - $transformer = new SanitizeHTMLTransformer(null, $this->cacheDir); - return $transformer->transform($string); + return $this->htmlTagHelper->getPurify($string); } /** From aede23144ad805785f901d5e4ff45944cc1687ec Mon Sep 17 00:00:00 2001 From: Makar Sichevoy Date: Wed, 27 May 2015 10:08:14 +0300 Subject: [PATCH 21/47] CRM-2965: Add description field to ActivityListItem - merge --- .../Provider/ActivityListChainProvider.php | 14 +++++- .../Resources/config/services.yml | 1 + .../ActivityListChainProviderTest.php | 10 ++++- .../Tests/Unit/Tools/HtmlTagHelperTest.php | 43 +++++++++++++------ .../Tests/Unit/Twig/HtmlTagExtensionTest.php | 27 +----------- .../Bundle/UIBundle/Twig/HtmlTagExtension.php | 5 +-- 6 files changed, 54 insertions(+), 46 deletions(-) diff --git a/src/Oro/Bundle/ActivityListBundle/Provider/ActivityListChainProvider.php b/src/Oro/Bundle/ActivityListBundle/Provider/ActivityListChainProvider.php index 7546d143d31..548a490cd7d 100644 --- a/src/Oro/Bundle/ActivityListBundle/Provider/ActivityListChainProvider.php +++ b/src/Oro/Bundle/ActivityListBundle/Provider/ActivityListChainProvider.php @@ -16,6 +16,7 @@ use Oro\Bundle\ActivityListBundle\Model\ActivityListDateProviderInterface; use Oro\Bundle\ActivityListBundle\Model\ActivityListGroupProviderInterface; use Oro\Bundle\CommentBundle\Model\CommentProviderInterface; +use Oro\Bundle\UIBundle\Tools\HtmlTagHelper; /** * Class ActivityListChainProvider @@ -42,22 +43,28 @@ class ActivityListChainProvider /** @var array */ protected $targetClasses = []; + /** @var HtmlTagHelper */ + protected $htmlTagHelper; + /** * @param DoctrineHelper $doctrineHelper * @param ConfigManager $configManager * @param TranslatorInterface $translator * @param EntityRoutingHelper $routingHelper + * @param HtmlTagHelper $htmlTagHelper */ public function __construct( DoctrineHelper $doctrineHelper, ConfigManager $configManager, TranslatorInterface $translator, - EntityRoutingHelper $routingHelper + EntityRoutingHelper $routingHelper, + HtmlTagHelper $htmlTagHelper ) { $this->doctrineHelper = $doctrineHelper; $this->configManager = $configManager; $this->translator = $translator; $this->routingHelper = $routingHelper; + $this->htmlTagHelper = $htmlTagHelper; } /** @@ -273,7 +280,10 @@ protected function getActivityListEntityForEntity( } $list->setSubject($provider->getSubject($entity)); - $list->setDescription($provider->getDescription($entity)); + $desctription = $this->htmlTagHelper->getStripped( + $this->htmlTagHelper->getPurify($provider->getDescription($entity)) + ); + $list->setDescription($desctription); if ($this->hasCustomDate($provider)) { $list->setCreatedAt($provider->getDate($entity)); $list->setUpdatedAt($provider->getDate($entity)); diff --git a/src/Oro/Bundle/ActivityListBundle/Resources/config/services.yml b/src/Oro/Bundle/ActivityListBundle/Resources/config/services.yml index f6fc95cf6f6..d175112b271 100644 --- a/src/Oro/Bundle/ActivityListBundle/Resources/config/services.yml +++ b/src/Oro/Bundle/ActivityListBundle/Resources/config/services.yml @@ -77,6 +77,7 @@ services: - @oro_entity_config.config_manager - @translator - @oro_entity.routing_helper + - @oro_ui.html_tag_helper oro_activity_list.entity_config_dumper.extension: class: %oro_activity_list.entity_config_dumper.extension.class% diff --git a/src/Oro/Bundle/ActivityListBundle/Tests/Unit/Provider/ActivityListChainProviderTest.php b/src/Oro/Bundle/ActivityListBundle/Tests/Unit/Provider/ActivityListChainProviderTest.php index cbf2324f9b7..308d0f1a6de 100644 --- a/src/Oro/Bundle/ActivityListBundle/Tests/Unit/Provider/ActivityListChainProviderTest.php +++ b/src/Oro/Bundle/ActivityListBundle/Tests/Unit/Provider/ActivityListChainProviderTest.php @@ -3,7 +3,6 @@ namespace Oro\Bundle\ActivityListBundle\Tests\Unit\Provider; use Oro\Bundle\ActivityListBundle\Entity\ActivityList; -use Oro\Bundle\ActivityListBundle\Model\ActivityListProviderInterface; use Oro\Bundle\ActivityListBundle\Provider\ActivityListChainProvider; use Oro\Bundle\ActivityListBundle\Tests\Unit\Placeholder\Fixture\TestTarget; use Oro\Bundle\ActivityListBundle\Tests\Unit\Provider\Fixture\TestActivityProvider; @@ -27,6 +26,9 @@ class ActivityListChainProviderTest extends \PHPUnit_Framework_TestCase /** @var \PHPUnit_Framework_MockObject_MockObject */ protected $translator; + /** @var \PHPUnit_Framework_MockObject_MockObject */ + protected $htmlTagHelper; + /** @var TestActivityProvider */ protected $testActivityProvider; @@ -43,6 +45,9 @@ public function setUp() ->getMock(); $this->translator = $this->getMockBuilder('Symfony\Component\Translation\TranslatorInterface') ->getMock(); + $this->htmlTagHelper = $this->getMockBuilder('Oro\Bundle\UIBundle\Tools\HtmlTagHelper') + ->disableOriginalConstructor() + ->getMock(); $this->testActivityProvider = new TestActivityProvider(); @@ -50,7 +55,8 @@ public function setUp() $this->doctrineHelper, $this->configManager, $this->translator, - $this->routeHelper + $this->routeHelper, + $this->htmlTagHelper ); $this->provider->addProvider($this->testActivityProvider); } diff --git a/src/Oro/Bundle/UIBundle/Tests/Unit/Tools/HtmlTagHelperTest.php b/src/Oro/Bundle/UIBundle/Tests/Unit/Tools/HtmlTagHelperTest.php index a02b8f0a5c9..f54acc4ef3a 100644 --- a/src/Oro/Bundle/UIBundle/Tests/Unit/Tools/HtmlTagHelperTest.php +++ b/src/Oro/Bundle/UIBundle/Tests/Unit/Tools/HtmlTagHelperTest.php @@ -19,33 +19,24 @@ protected function setUp() $this->helper = new HtmlTagHelper($this->htmlTagProvider); } - public function testGetStrippedBody() + public function testGetStripped() { - $actualString = '
test
'; + $actualString = '
test
'; $expectedString = 'test'; $this->assertEquals($expectedString, $this->helper->getStripped($actualString)); } /** - * @dataProvider shortBodiesProvider + * @dataProvider shortStringProvider */ - public function testGetShortBody($expected, $actual, $maxLength) + public function testGetShort($expected, $actual, $maxLength) { $shortBody = $this->helper->getShort($actual, $maxLength); $this->assertEquals($expected, $shortBody); } - public static function bodiesProvider() - { - return [ - ['

Hello

', '

Hello

', false], - ['

Hello

', '

Hello

Other content
', false], - ['

H

H
', '

H

H
', true] - ]; - } - - public static function shortBodiesProvider() + public static function shortStringProvider() { return [ ['abc abc abc', 'abc abc abc abc ', 12], @@ -53,4 +44,28 @@ public static function shortBodiesProvider() ['abcab', 'abcabcabcabc', 5], ]; } + + public function testHtmlPurify() + { + $testString = << + + + + + + +
no subject
+ + + +STR; + $this->assertEquals( + '
no subject
', + trim($this->helper->getPurify($testString)) + ); + } } diff --git a/src/Oro/Bundle/UIBundle/Tests/Unit/Twig/HtmlTagExtensionTest.php b/src/Oro/Bundle/UIBundle/Tests/Unit/Twig/HtmlTagExtensionTest.php index 4ae5bd99523..381b630247a 100644 --- a/src/Oro/Bundle/UIBundle/Tests/Unit/Twig/HtmlTagExtensionTest.php +++ b/src/Oro/Bundle/UIBundle/Tests/Unit/Twig/HtmlTagExtensionTest.php @@ -19,7 +19,8 @@ class HtmlTagExtensionTest extends \PHPUnit_Framework_TestCase protected function setUp() { - $this->htmlTagHelper = $this->getMock('Oro\Bundle\FormBundle\Provider\HtmlTagHelper'); + $this->htmlTagHelper = $this->getMockBuilder('Oro\Bundle\UIBundle\Tools\HtmlTagHelper') + ->disableOriginalConstructor()->getMock(); $this->extension = new HtmlTagExtension($this->htmlTagHelper); } @@ -45,28 +46,4 @@ public function testGetFilters() $this->assertEquals($callable[0], $this->extension); $this->assertEquals($callable[1], 'tagFilter'); } - - public function testHtmlPurify() - { - $testString = << - - - - - - -
no subject
- - - -STR; - $this->assertEquals( - '
no subject
', - trim($this->extension->htmlPurify($testString)) - ); - } } diff --git a/src/Oro/Bundle/UIBundle/Twig/HtmlTagExtension.php b/src/Oro/Bundle/UIBundle/Twig/HtmlTagExtension.php index e49881c6141..1b2b851f1c0 100644 --- a/src/Oro/Bundle/UIBundle/Twig/HtmlTagExtension.php +++ b/src/Oro/Bundle/UIBundle/Twig/HtmlTagExtension.php @@ -16,9 +16,8 @@ class HtmlTagExtension extends \Twig_Extension /** * @param HtmlTagHelper $htmlTagHelper */ - public function __construct( - HtmlTagHelper $htmlTagHelper - ) { + public function __construct(HtmlTagHelper $htmlTagHelper) + { $this->htmlTagHelper = $htmlTagHelper; } From 41e85e9fd57641d8d50260508540c13ec47debb4 Mon Sep 17 00:00:00 2001 From: Makar Sichevoy Date: Wed, 27 May 2015 10:33:19 +0300 Subject: [PATCH 22/47] CRM-2965: Add description field to ActivityListItem - subject style --- .../Resources/views/ActivityList/js/view.js.twig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Oro/Bundle/ActivityListBundle/Resources/views/ActivityList/js/view.js.twig b/src/Oro/Bundle/ActivityListBundle/Resources/views/ActivityList/js/view.js.twig index 9fe262e57a7..1d42fdda8b7 100644 --- a/src/Oro/Bundle/ActivityListBundle/Resources/views/ActivityList/js/view.js.twig +++ b/src/Oro/Bundle/ActivityListBundle/Resources/views/ActivityList/js/view.js.twig @@ -26,7 +26,7 @@
{% block activityShortMessage %} - <%= subject %> + <%= subject %> <% if (!_.isUndefined(description) && !_.isEmpty(description)) { %> - <%= description %> <% } %> From 062223179909f0e8c1e5002e13626e82d0331a5b Mon Sep 17 00:00:00 2001 From: Makar Sichevoy Date: Wed, 27 May 2015 11:13:02 +0300 Subject: [PATCH 23/47] CRM-2965: Add description field to ActivityListItem --- src/Oro/Bundle/EmailBundle/Resources/config/services.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Oro/Bundle/EmailBundle/Resources/config/services.yml b/src/Oro/Bundle/EmailBundle/Resources/config/services.yml index 3098871fa74..d49da7ce69d 100644 --- a/src/Oro/Bundle/EmailBundle/Resources/config/services.yml +++ b/src/Oro/Bundle/EmailBundle/Resources/config/services.yml @@ -4,7 +4,6 @@ parameters: oro_email.email_folder.model.class: Oro\Bundle\EmailBundle\Model\FolderType oro_email.email.cache.manager.class: Oro\Bundle\EmailBundle\Cache\EmailCacheManager oro_email.email_holder_helper.class: Oro\Bundle\EmailBundle\Tools\EmailHolderHelper -# oro_email.email_helper.class: Oro\Bundle\EmailBundle\Tools\EmailHelper oro_email.email.address.helper.class: Oro\Bundle\EmailBundle\Tools\EmailAddressHelper oro_email.email.address.manager.class: Oro\Bundle\EmailBundle\Entity\Manager\EmailAddressManager oro_email.email.owner.provider.class: Oro\Bundle\EmailBundle\Entity\Provider\EmailOwnerProvider From 5903250694ebd794ed5a1c1f92019553897d89cc Mon Sep 17 00:00:00 2001 From: Vova Soroka Date: Wed, 13 May 2015 20:44:45 +0300 Subject: [PATCH 24/47] Fix Translator after update to Symfony 2.3.28. bug #14268 [Translator] Cache does not take fallback locales into consideration (sf2.3) --- src/Oro/Bundle/TranslationBundle/Translation/Translator.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Oro/Bundle/TranslationBundle/Translation/Translator.php b/src/Oro/Bundle/TranslationBundle/Translation/Translator.php index 55a815c2245..8f3ae32410a 100644 --- a/src/Oro/Bundle/TranslationBundle/Translation/Translator.php +++ b/src/Oro/Bundle/TranslationBundle/Translation/Translator.php @@ -128,7 +128,8 @@ protected function loadCatalogue($locale) && isset($this->dynamicResources[$locale]) && !empty($this->dynamicResources[$locale]) ) { - $catalogueFile = $this->options['cache_dir'] . '/catalogue.' . $locale . '.php'; + $catalogueFile = $this->options['cache_dir'] + . '/catalogue.' . $locale . '.' . sha1(serialize($this->getFallbackLocales())) . '.php'; if (is_file($catalogueFile)) { $time = filemtime($catalogueFile); /** @var DynamicResourceInterface $dynamicResource */ From 4494a9129f391bc83c407f8137b5cf02a94bd2a4 Mon Sep 17 00:00:00 2001 From: Alexander Nezdoiminoga Date: Mon, 25 May 2015 15:49:03 +0300 Subject: [PATCH 25/47] CRM-3336: tracking processor, batches added, decreased RETRY_COUNT, max execution time set to 5min --- .../Processor/TrackingProcessor.php | 151 ++++++++++++++---- 1 file changed, 119 insertions(+), 32 deletions(-) diff --git a/src/Oro/Bundle/TrackingBundle/Processor/TrackingProcessor.php b/src/Oro/Bundle/TrackingBundle/Processor/TrackingProcessor.php index de6e9acc97f..0ac74db4589 100644 --- a/src/Oro/Bundle/TrackingBundle/Processor/TrackingProcessor.php +++ b/src/Oro/Bundle/TrackingBundle/Processor/TrackingProcessor.php @@ -38,10 +38,10 @@ class TrackingProcessor implements LoggerAwareInterface const BATCH_SIZE = 100; /** Max retries to identify tracking visit */ - const MAX_RETRIES = 100; + const MAX_RETRIES = 5; /** The maximum execution time (in minutes) */ - const MAX_EXEC_TIME_IN_MIN = 30; + const MAX_EXEC_TIME_IN_MIN = 5; /** @var ManagerRegistry */ protected $doctrine; @@ -67,7 +67,7 @@ class TrackingProcessor implements LoggerAwareInterface /** @var \DateTime start time */ protected $startTime = null; - /** @var \DateInterval|bool */ + /** @var \DateInterval|bool */ protected $maxExecTimeout = false; /** @@ -80,8 +80,8 @@ public function __construct(ManagerRegistry $doctrine, TrackingEventIdentificati $this->trackingIdentification = $trackingIdentification; $this->deviceDetector = new DeviceDetectorFactory(); - $this->startTime = $this->getCurrentUtcDateTime(); - $this->maxExecTimeout = self::MAX_EXEC_TIME_IN_MIN > 0 + $this->startTime = $this->getCurrentUtcDateTime(); + $this->maxExecTimeout = self::MAX_EXEC_TIME_IN_MIN > 0 ? new \DateInterval('PT' . self::MAX_EXEC_TIME_IN_MIN . 'M') : false; } @@ -98,23 +98,22 @@ public function process() $this->logger = new NullLogger(); } - $totalEvents = $this->getEventsCount(); - $totalBatches = number_format(ceil($totalEvents / self::BATCH_SIZE)); - $this->logger->notice( - sprintf( - 'Total events to be processed - %s (%s batches).', - number_format($totalEvents), - $totalBatches - ) - ); - + $this->logger->notice('Check new visits...'); + $totalEvents = $this->getEventsCount(); if ($totalEvents > 0) { - $this->logger->notice('Processing new visits...'); + $totalBatches = number_format(ceil($totalEvents / self::BATCH_SIZE)); + $this->logger->notice( + sprintf( + 'Total visits to be processed - %s (%s batches).', + number_format($totalEvents), + $totalBatches + ) + ); while ($this->processVisits()) { $this->logger->notice( sprintf( 'Batch #%d of %s processed at %s.', - ++$this->processedBatches, + number_format(++$this->processedBatches), $totalBatches, date('Y-m-d H:i:s') ) @@ -127,22 +126,58 @@ public function process() } $this->logger->notice('Recheck previous visit identifiers...'); - while ($this->identifyPrevVisits()) { - if ($this->checkMaxExecutionTime()) { - return; + $totalEvents = $this->getIdentifyPrevVisitsCount(); + if ($totalEvents > 0) { + $totalBatches = number_format(ceil($totalEvents / self::BATCH_SIZE)); + $this->processedBatches = 0; + $this->logger->notice( + sprintf( + 'Total previous visit identifiers to be processed - %s (%s batches).', + number_format($totalEvents), + $totalBatches + ) + ); + while ($this->identifyPrevVisits()) { + $this->logger->notice( + sprintf( + 'Batch #%d of %s processed at %s.', + number_format(++$this->processedBatches), + $totalBatches, + date('Y-m-d H:i:s') + ) + ); + if ($this->checkMaxExecutionTime()) { + return; + } } - - $this->logger->notice('Try to process Next batch'); } $this->logger->notice('Recheck previous visit events...'); - $this->skipList = []; - while ($this->identifyPrevVisitEvents()) { - if ($this->checkMaxExecutionTime()) { - return; + $totalEvents = $this->getIdentifyPrevVisitEventsCount(); + if ($totalEvents > 0) { + $totalBatches = number_format(ceil($totalEvents / self::BATCH_SIZE)); + $this->processedBatches = 0; + $this->logger->notice( + sprintf( + 'Total previous visit events to be processed - %s (%s batches).', + number_format($totalEvents), + $totalBatches + ) + ); + $this->skipList = []; + while ($this->identifyPrevVisitEvents()) { + $this->logger->notice( + sprintf( + 'Batch #%d of %s processed at %s.', + number_format(++$this->processedBatches), + $totalBatches, + date('Y-m-d H:i:s') + ) + ); + if ($this->checkMaxExecutionTime()) { + return; + } } - - $this->logger->notice('Try to process Next batch'); } $this->logger->notice('Done'); @@ -159,6 +194,7 @@ protected function checkMaxExecutionTime() $date = $this->getCurrentUtcDateTime(); if ($date->sub($this->maxExecTimeout) >= $this->startTime) { $this->logger->notice('Exit because allocated time frame elapsed.'); + return true; } } @@ -169,7 +205,7 @@ protected function checkMaxExecutionTime() /** * Returns count of web events to be processed. * - * @return mixed + * @return integer */ protected function getEventsCount() { @@ -183,6 +219,55 @@ protected function getEventsCount() return $queryBuilder->getQuery()->getSingleScalarResult(); } + /** + * Returns count of not identified web visits to be processed. + * + * @return integer + */ + protected function getIdentifyPrevVisitsCount() + { + $em = $this->getEntityManager(); + $queryBuilder = $em + ->getRepository(self::TRACKING_VISIT_ENTITY) + ->createQueryBuilder('entity'); + $queryBuilder + ->select('COUNT (entity.id)') + ->where('entity.identifierDetected = false') + ->andWhere('entity.parsedUID > 0') + ->andWhere('entity.parsingCount < :maxRetries') + ->orderBy('entity.firstActionTime', 'ASC') + ->setParameter('maxRetries', self::MAX_RETRIES); + + if (count($this->skipList)) { + $queryBuilder->andWhere('entity.id not in(' . implode(',', $this->skipList) . ')'); + } + + return $queryBuilder->getQuery()->getSingleScalarResult(); + } + + /** + * Returns count of tracking visit events to be processed. + * + * @return integer + */ + protected function getIdentifyPrevVisitEventsCount() + { + $em = $this->getEntityManager(); + $queryBuilder = $em + ->getRepository(self::TRACKING_VISIT_EVENT_ENTITY) + ->createQueryBuilder('entity'); + $queryBuilder + ->select('COUNT (entity.id)') + ->andWhere('entity.parsingCount < :maxRetries') + ->setParameter('maxRetries', self::MAX_RETRIES); + + if (count($this->skipList)) { + $queryBuilder->andWhere('entity.id not in(' . implode(',', $this->skipList) . ')'); + } + + return $queryBuilder->getQuery()->getSingleScalarResult(); + } + /** * Process previous visit events * @@ -197,7 +282,8 @@ protected function identifyPrevVisitEvents() $queryBuilder ->select('entity') ->andWhere('entity.parsingCount < :maxRetries') - ->setParameter('maxRetries', self::MAX_RETRIES); + ->setParameter('maxRetries', self::MAX_RETRIES) + ->setMaxResults(self::BATCH_SIZE); if (count($this->skipList)) { $queryBuilder->andWhere('entity.id not in(' . implode(',', $this->skipList) . ')'); @@ -243,7 +329,8 @@ protected function identifyPrevVisits() ->andWhere('entity.parsedUID > 0') ->andWhere('entity.parsingCount < :maxRetries') ->orderBy('entity.firstActionTime', 'ASC') - ->setParameter('maxRetries', self::MAX_RETRIES); + ->setParameter('maxRetries', self::MAX_RETRIES) + ->setMaxResults(self::BATCH_SIZE); if (count($this->skipList)) { $queryBuilder->andWhere('entity.id not in(' . implode(',', $this->skipList) . ')'); @@ -332,7 +419,7 @@ function (&$value) { $this->getEntityManager()->createQueryBuilder() ->update(self::TRACKING_VISIT_EVENT_ENTITY, 'event') ->set('event.' . $associationName, ':identifier') - ->where('event.visit in(' . implode(',', $subSelect) .')') + ->where('event.visit in(' . implode(',', $subSelect) . ')') ->setParameter('identifier', $identifier) ->getQuery() ->execute(); From 1f9fc79d249f2cb01078f86cdc1f33efd2d0bf9e Mon Sep 17 00:00:00 2001 From: Alexander Nezdoiminoga Date: Thu, 28 May 2015 16:03:58 +0300 Subject: [PATCH 26/47] CRM-3336: Tracking parse command refactoring - batches added to all while's - max exec time set to 5min - max retries count decreased to 5 instead of 100 - option "--max-execution-time" added for command in case we will need to disable or change max time limitation - logging improved, now with option "-v" we will see more informative output --- .../TrackingBundle/Command/TrackCommand.php | 14 +++- .../Processor/TrackingProcessor.php | 66 ++++++++++--------- 2 files changed, 49 insertions(+), 31 deletions(-) diff --git a/src/Oro/Bundle/TrackingBundle/Command/TrackCommand.php b/src/Oro/Bundle/TrackingBundle/Command/TrackCommand.php index e0270072d61..c6403df04bc 100644 --- a/src/Oro/Bundle/TrackingBundle/Command/TrackCommand.php +++ b/src/Oro/Bundle/TrackingBundle/Command/TrackCommand.php @@ -3,6 +3,7 @@ namespace Oro\Bundle\TrackingBundle\Command; use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; +use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -31,7 +32,13 @@ protected function configure() { $this ->setName(self::COMMAND_NAME) - ->setDescription('Parse tracking logs'); + ->setDescription('Parse tracking logs') + ->addOption( + 'max-execution-time', + 'm', + InputOption::VALUE_OPTIONAL, + 'Max execution time (in minutes). "0" means - unlimited. (default: 5)' + ); } /** @@ -49,6 +56,11 @@ protected function execute(InputInterface $input, OutputInterface $output) /** @var TrackingProcessor $processor */ $processor = $this->getContainer()->get('oro_tracking.processor.tracking_processor'); + $maxExecutionTime = $input->getOption('max-execution-time'); + if ($maxExecutionTime && is_numeric($maxExecutionTime)) { + $processor->setMaxExecutionTime($maxExecutionTime); + } + $processor->setLogger($logger); $processor->process(); diff --git a/src/Oro/Bundle/TrackingBundle/Processor/TrackingProcessor.php b/src/Oro/Bundle/TrackingBundle/Processor/TrackingProcessor.php index 0ac74db4589..99bc4f43553 100644 --- a/src/Oro/Bundle/TrackingBundle/Processor/TrackingProcessor.php +++ b/src/Oro/Bundle/TrackingBundle/Processor/TrackingProcessor.php @@ -40,9 +40,6 @@ class TrackingProcessor implements LoggerAwareInterface /** Max retries to identify tracking visit */ const MAX_RETRIES = 5; - /** The maximum execution time (in minutes) */ - const MAX_EXEC_TIME_IN_MIN = 5; - /** @var ManagerRegistry */ protected $doctrine; @@ -70,6 +67,9 @@ class TrackingProcessor implements LoggerAwareInterface /** @var \DateInterval|bool */ protected $maxExecTimeout = false; + /** Default max execution time (in minutes) */ + protected $maxExecTime = 5; + /** * @param ManagerRegistry $doctrine * @param TrackingEventIdentificationProvider $trackingIdentification @@ -81,11 +81,22 @@ public function __construct(ManagerRegistry $doctrine, TrackingEventIdentificati $this->deviceDetector = new DeviceDetectorFactory(); $this->startTime = $this->getCurrentUtcDateTime(); - $this->maxExecTimeout = self::MAX_EXEC_TIME_IN_MIN > 0 - ? new \DateInterval('PT' . self::MAX_EXEC_TIME_IN_MIN . 'M') + $this->maxExecTimeout = $this->maxExecTime > 0 + ? new \DateInterval('PT' . $this->maxExecTime . 'M') : false; } + /** + * @param integer $minutes + */ + public function setMaxExecutionTime($minutes = null) + { + if ($minutes !== null) { + $this->maxExecTime = $minutes; + $this->maxExecTimeout = $minutes > 0 ? new \DateInterval('PT' . $minutes . 'M') : false; + } + } + /** * Process tracking data */ @@ -99,6 +110,7 @@ public function process() } $this->logger->notice('Check new visits...'); + $this->logger->notice($this->maxExecTime . '//' . ($this->maxExecTimeout->format('%I minutes'))); $totalEvents = $this->getEventsCount(); if ($totalEvents > 0) { $totalBatches = number_format(ceil($totalEvents / self::BATCH_SIZE)); @@ -110,15 +122,7 @@ public function process() ) ); while ($this->processVisits()) { - $this->logger->notice( - sprintf( - 'Batch #%d of %s processed at %s.', - number_format(++$this->processedBatches), - $totalBatches, - date('Y-m-d H:i:s') - ) - ); - + $this->logBatch(++$this->processedBatches, $totalBatches); if ($this->checkMaxExecutionTime()) { return; } @@ -138,14 +142,7 @@ public function process() ) ); while ($this->identifyPrevVisits()) { - $this->logger->notice( - sprintf( - 'Batch #%d of %s processed at %s.', - number_format(++$this->processedBatches), - $totalBatches, - date('Y-m-d H:i:s') - ) - ); + $this->logBatch(++$this->processedBatches, $totalBatches); if ($this->checkMaxExecutionTime()) { return; } @@ -166,14 +163,7 @@ public function process() ); $this->skipList = []; while ($this->identifyPrevVisitEvents()) { - $this->logger->notice( - sprintf( - 'Batch #%d of %s processed at %s.', - number_format(++$this->processedBatches), - $totalBatches, - date('Y-m-d H:i:s') - ) - ); + $this->logBatch(++$this->processedBatches, $totalBatches); if ($this->checkMaxExecutionTime()) { return; } @@ -183,6 +173,22 @@ public function process() $this->logger->notice('Done'); } + /** + * @param integer $processed + * @param integer $total + */ + protected function logBatch($processed, $total) + { + $this->logger->notice( + sprintf( + 'Batch #%d of %s processed at %s.', + number_format($processed), + $total, + date('Y-m-d H:i:s') + ) + ); + } + /** * Checks of process max execution time * From 86522b40cb5dd8cb7e6533a7e8414519229edfcd Mon Sep 17 00:00:00 2001 From: Alexander Nezdoiminoga Date: Thu, 28 May 2015 16:10:53 +0300 Subject: [PATCH 27/47] CRM-3336: Tracking parse command fix --- src/Oro/Bundle/TrackingBundle/Processor/TrackingProcessor.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Oro/Bundle/TrackingBundle/Processor/TrackingProcessor.php b/src/Oro/Bundle/TrackingBundle/Processor/TrackingProcessor.php index 99bc4f43553..d3bc9a16e08 100644 --- a/src/Oro/Bundle/TrackingBundle/Processor/TrackingProcessor.php +++ b/src/Oro/Bundle/TrackingBundle/Processor/TrackingProcessor.php @@ -175,13 +175,13 @@ public function process() /** * @param integer $processed - * @param integer $total + * @param string $total */ protected function logBatch($processed, $total) { $this->logger->notice( sprintf( - 'Batch #%d of %s processed at %s.', + 'Batch #%s of %s processed at %s.', number_format($processed), $total, date('Y-m-d H:i:s') From 70a63b1c3559c5fdc8c5354a213907de6cbe8d7d Mon Sep 17 00:00:00 2001 From: Alexander Nezdoiminoga Date: Thu, 28 May 2015 16:17:51 +0300 Subject: [PATCH 28/47] CRM-3336: Tracking parse command - remove debug logging --- src/Oro/Bundle/TrackingBundle/Processor/TrackingProcessor.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Oro/Bundle/TrackingBundle/Processor/TrackingProcessor.php b/src/Oro/Bundle/TrackingBundle/Processor/TrackingProcessor.php index d3bc9a16e08..13442d2252d 100644 --- a/src/Oro/Bundle/TrackingBundle/Processor/TrackingProcessor.php +++ b/src/Oro/Bundle/TrackingBundle/Processor/TrackingProcessor.php @@ -110,7 +110,6 @@ public function process() } $this->logger->notice('Check new visits...'); - $this->logger->notice($this->maxExecTime . '//' . ($this->maxExecTimeout->format('%I minutes'))); $totalEvents = $this->getEventsCount(); if ($totalEvents > 0) { $totalBatches = number_format(ceil($totalEvents / self::BATCH_SIZE)); From efc353ad3842639c7a784b031c25e7d1f7a0848f Mon Sep 17 00:00:00 2001 From: Yurii Muratov Date: Thu, 28 May 2015 17:36:54 +0300 Subject: [PATCH 29/47] CRM-3336: tracking processor - Return tracking event table to the report - Fix performance issue in processor - update documentation --- src/Oro/Bundle/TrackingBundle/Processor/TrackingProcessor.php | 2 +- src/Oro/Bundle/TrackingBundle/README.md | 4 +++- src/Oro/Bundle/TrackingBundle/Resources/config/oro/entity.yml | 2 -- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Oro/Bundle/TrackingBundle/Processor/TrackingProcessor.php b/src/Oro/Bundle/TrackingBundle/Processor/TrackingProcessor.php index 13442d2252d..96859fd2e8c 100644 --- a/src/Oro/Bundle/TrackingBundle/Processor/TrackingProcessor.php +++ b/src/Oro/Bundle/TrackingBundle/Processor/TrackingProcessor.php @@ -467,7 +467,7 @@ protected function processVisits() ->getRepository(self::TRACKING_EVENT_ENTITY) ->createQueryBuilder('entity') ->where('entity.parsed = false') - ->orderBy('entity.createdAt', 'ASC') + ->orderBy('entity.id', 'ASC') ->setMaxResults(self::BATCH_SIZE); $entities = $queryBuilder->getQuery()->getResult(); diff --git a/src/Oro/Bundle/TrackingBundle/README.md b/src/Oro/Bundle/TrackingBundle/README.md index 4db1933418e..1a3cf7426d9 100644 --- a/src/Oro/Bundle/TrackingBundle/README.md +++ b/src/Oro/Bundle/TrackingBundle/README.md @@ -163,7 +163,7 @@ class TestCustomerIdentification implements TrackingEventIdentifierInterface User can crate reports based on tracked event data. -The main entity for this data is **Visitor event**. This entity have next fields: +The main entity for this data is **Visitor event** - parsed web event data related to customer, campaign order or other customer data. This entity have next fields: - **Type**. Virtual string field. Type of event. Each tracking website can use own list of event types. @@ -196,3 +196,5 @@ The main entity for this data is **Visitor event**. This entity have next fields - **Tracking website** Link to website tracking config record. - List of connected records to the event event entity. + +Additionally, there is **Tracking Event** table - original web event data recorded from the website diff --git a/src/Oro/Bundle/TrackingBundle/Resources/config/oro/entity.yml b/src/Oro/Bundle/TrackingBundle/Resources/config/oro/entity.yml index ec9f45a6b1b..3af53908e43 100644 --- a/src/Oro/Bundle/TrackingBundle/Resources/config/oro/entity.yml +++ b/src/Oro/Bundle/TrackingBundle/Resources/config/oro/entity.yml @@ -1,11 +1,9 @@ oro_entity: exclusions: - { entity: Oro\Bundle\TrackingBundle\Entity\TrackingData } - - { entity: Oro\Bundle\TrackingBundle\Entity\TrackingEvent } - { entity: Oro\Bundle\TrackingBundle\Entity\TrackingEventDictionary } - { entity: Oro\Bundle\TrackingBundle\Entity\TrackingVisit } - { entity: Oro\Bundle\TrackingBundle\Entity\TrackingVisitEvent, field: parsingCount } - - { entity: Oro\Bundle\TrackingBundle\Entity\TrackingVisitEvent, field: webEvent } - { entity: Oro\Bundle\TrackingBundle\Entity\TrackingVisitEvent, field: event } - { entity: Oro\Bundle\TrackingBundle\Entity\TrackingVisitEvent, field: visit } From b9db2bd5c28a2346f58ee752e2b30bae0a3f2b1b Mon Sep 17 00:00:00 2001 From: Valentine Velikiy Date: Thu, 28 May 2015 18:47:23 +0300 Subject: [PATCH 30/47] CRM-2965: Add description field to ActivityListItem. - Fixed typo. - Added attribute definition. - Added new lines. - strrpos replaced with mb_strrpos. - Added encoding detection. - Renamed methods. --- .../Provider/ActivityListChainProvider.php | 6 ++-- .../Provider/EmailActivityListProvider.php | 6 ++-- .../Tests/Unit/Tools/HtmlTagHelperTest.php | 7 +++-- .../Bundle/UIBundle/Tools/HtmlTagHelper.php | 28 +++++++++++-------- .../Bundle/UIBundle/Twig/HtmlTagExtension.php | 4 +-- 5 files changed, 29 insertions(+), 22 deletions(-) diff --git a/src/Oro/Bundle/ActivityListBundle/Provider/ActivityListChainProvider.php b/src/Oro/Bundle/ActivityListBundle/Provider/ActivityListChainProvider.php index 548a490cd7d..e804ff17cb7 100644 --- a/src/Oro/Bundle/ActivityListBundle/Provider/ActivityListChainProvider.php +++ b/src/Oro/Bundle/ActivityListBundle/Provider/ActivityListChainProvider.php @@ -280,10 +280,10 @@ protected function getActivityListEntityForEntity( } $list->setSubject($provider->getSubject($entity)); - $desctription = $this->htmlTagHelper->getStripped( - $this->htmlTagHelper->getPurify($provider->getDescription($entity)) + $description = $this->htmlTagHelper->stripTags( + $this->htmlTagHelper->purify($provider->getDescription($entity)) ); - $list->setDescription($desctription); + $list->setDescription($description); if ($this->hasCustomDate($provider)) { $list->setCreatedAt($provider->getDate($entity)); $list->setUpdatedAt($provider->getDate($entity)); diff --git a/src/Oro/Bundle/EmailBundle/Provider/EmailActivityListProvider.php b/src/Oro/Bundle/EmailBundle/Provider/EmailActivityListProvider.php index e7d28972f0e..57ff4ea7f2b 100644 --- a/src/Oro/Bundle/EmailBundle/Provider/EmailActivityListProvider.php +++ b/src/Oro/Bundle/EmailBundle/Provider/EmailActivityListProvider.php @@ -124,9 +124,9 @@ public function getDescription($entity) /** @var $entity Email */ if ($entity->getEmailBody()) { $body = $entity->getEmailBody()->getBodyContent(); - $content = $this->htmlTagHelper->getPurify($body); - $content = $this->htmlTagHelper->getStripped($content); - $content = $this->htmlTagHelper->getShort($content); + $content = $this->htmlTagHelper->purify($body); + $content = $this->htmlTagHelper->stripTags($content); + $content = $this->htmlTagHelper->shorten($content); return $content; } diff --git a/src/Oro/Bundle/UIBundle/Tests/Unit/Tools/HtmlTagHelperTest.php b/src/Oro/Bundle/UIBundle/Tests/Unit/Tools/HtmlTagHelperTest.php index f54acc4ef3a..da14c1e3ef4 100644 --- a/src/Oro/Bundle/UIBundle/Tests/Unit/Tools/HtmlTagHelperTest.php +++ b/src/Oro/Bundle/UIBundle/Tests/Unit/Tools/HtmlTagHelperTest.php @@ -24,7 +24,7 @@ public function testGetStripped() $actualString = '
test
'; $expectedString = 'test'; - $this->assertEquals($expectedString, $this->helper->getStripped($actualString)); + $this->assertEquals($expectedString, $this->helper->stripTags($actualString)); } /** @@ -32,13 +32,14 @@ public function testGetStripped() */ public function testGetShort($expected, $actual, $maxLength) { - $shortBody = $this->helper->getShort($actual, $maxLength); + $shortBody = $this->helper->shorten($actual, $maxLength); $this->assertEquals($expected, $shortBody); } public static function shortStringProvider() { return [ + ['абв абв абв', 'абв абв абв абв ', 12], ['abc abc abc', 'abc abc abc abc ', 12], ['abc abc', 'abc abc abc abc abc', 8], ['abcab', 'abcabcabcabc', 5], @@ -65,7 +66,7 @@ public function testHtmlPurify() STR; $this->assertEquals( '
no subject
', - trim($this->helper->getPurify($testString)) + trim($this->helper->purify($testString)) ); } } diff --git a/src/Oro/Bundle/UIBundle/Tools/HtmlTagHelper.php b/src/Oro/Bundle/UIBundle/Tools/HtmlTagHelper.php index d0c740e1c23..2397ba47420 100644 --- a/src/Oro/Bundle/UIBundle/Tools/HtmlTagHelper.php +++ b/src/Oro/Bundle/UIBundle/Tools/HtmlTagHelper.php @@ -9,6 +9,9 @@ class HtmlTagHelper { const MAX_STRING_LENGTH = 500; + /** @var HtmlTagProvider */ + protected $htmlTagProvider; + /** @var string */ protected $cacheDir; @@ -28,10 +31,11 @@ public function __construct( * @param string $string * @return string */ - public function getPurify($string) + public function purify($string) { $transformer = new SanitizeHTMLTransformer(null, $this->cacheDir); - return $transformer->transform($string); + + return trim($transformer->transform($string)); } /** @@ -39,31 +43,33 @@ public function getPurify($string) * @param bool $uiAllowedTags * @return string */ - public function getStripped($string, $uiAllowedTags = false) + public function stripTags($string, $uiAllowedTags = false) { if ($uiAllowedTags) { return strip_tags($string, $this->htmlTagProvider->getAllowedTags()); } - return strip_tags($string); + + return trim(strip_tags($string)); } /** - * Get shorter text + * Shorten text * * @param string $string * @param int $maxLength * @return string */ - public function getShort($string, $maxLength = self::MAX_STRING_LENGTH) + public function shorten($string, $maxLength = self::MAX_STRING_LENGTH) { - if (mb_strlen($string) > $maxLength) { - $string = mb_substr($string, 0, $maxLength); - $lastOccurrencePos = strrpos($string, ' '); + $encoding = mb_detect_encoding($string); + if (mb_strlen($string, $encoding) > $maxLength) { + $string = mb_substr($string, 0, $maxLength, $encoding); + $lastOccurrencePos = mb_strrpos($string, ' ', null, $encoding); if ($lastOccurrencePos !== false) { - $string = mb_substr($string, 0, $lastOccurrencePos); + $string = mb_substr($string, 0, $lastOccurrencePos, $encoding); } } - return $string; + return trim($string); } } diff --git a/src/Oro/Bundle/UIBundle/Twig/HtmlTagExtension.php b/src/Oro/Bundle/UIBundle/Twig/HtmlTagExtension.php index 1b2b851f1c0..3890ae8b47b 100644 --- a/src/Oro/Bundle/UIBundle/Twig/HtmlTagExtension.php +++ b/src/Oro/Bundle/UIBundle/Twig/HtmlTagExtension.php @@ -39,7 +39,7 @@ public function getFilters() */ public function tagFilter($string) { - return $this->htmlTagHelper->getStripped($string); + return $this->htmlTagHelper->stripTags($string); } /** @@ -50,7 +50,7 @@ public function tagFilter($string) */ public function htmlPurify($string) { - return $this->htmlTagHelper->getPurify($string); + return $this->htmlTagHelper->purify($string); } /** From 81f239b383fc27d802b85904cd8f19be41453598 Mon Sep 17 00:00:00 2001 From: Ignat Shcheglovskyi Date: Sat, 25 Apr 2015 10:40:19 +0300 Subject: [PATCH 31/47] BAP-8093: Process exclude definition doesn't apply to existing process - fix import of exclude definitions --- src/Oro/Bundle/WorkflowBundle/Entity/ProcessDefinition.php | 3 ++- .../WorkflowBundle/Tests/Unit/Entity/ProcessDefinitionTest.php | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Oro/Bundle/WorkflowBundle/Entity/ProcessDefinition.php b/src/Oro/Bundle/WorkflowBundle/Entity/ProcessDefinition.php index 380009a9ee9..c0d540e11df 100644 --- a/src/Oro/Bundle/WorkflowBundle/Entity/ProcessDefinition.php +++ b/src/Oro/Bundle/WorkflowBundle/Entity/ProcessDefinition.php @@ -315,7 +315,8 @@ public function import(ProcessDefinition $definition) ->setLabel($definition->getLabel()) ->setRelatedEntity($definition->getRelatedEntity()) ->setExecutionOrder($definition->getExecutionOrder()) - ->setActionsConfiguration($definition->getActionsConfiguration()); + ->setActionsConfiguration($definition->getActionsConfiguration()) + ->setExcludeDefinitions($definition->getExcludeDefinitions()); return $this; } diff --git a/src/Oro/Bundle/WorkflowBundle/Tests/Unit/Entity/ProcessDefinitionTest.php b/src/Oro/Bundle/WorkflowBundle/Tests/Unit/Entity/ProcessDefinitionTest.php index 3709a0980a6..344bd4a5289 100644 --- a/src/Oro/Bundle/WorkflowBundle/Tests/Unit/Entity/ProcessDefinitionTest.php +++ b/src/Oro/Bundle/WorkflowBundle/Tests/Unit/Entity/ProcessDefinitionTest.php @@ -63,6 +63,7 @@ public function testImport() ->setEnabled(false) ->setRelatedEntity('My/Entity') ->setExecutionOrder(25) + ->setExcludeDefinitions(['foo']) ->setActionsConfiguration(array('key' => 'value')); $this->assertNotEquals($importedEntity->getName(), $this->entity->getName()); @@ -70,6 +71,7 @@ public function testImport() $this->assertNotEquals($importedEntity->getRelatedEntity(), $this->entity->getRelatedEntity()); $this->assertNotEquals($importedEntity->getExecutionOrder(), $this->entity->getExecutionOrder()); $this->assertNotEquals($importedEntity->getActionsConfiguration(), $this->entity->getActionsConfiguration()); + $this->assertNotEquals($importedEntity->getExcludeDefinitions(), $this->entity->getExcludeDefinitions()); $this->assertTrue($this->entity->isEnabled()); $this->entity->import($importedEntity); @@ -79,6 +81,7 @@ public function testImport() $this->assertEquals($importedEntity->getRelatedEntity(), $this->entity->getRelatedEntity()); $this->assertEquals($importedEntity->getExecutionOrder(), $this->entity->getExecutionOrder()); $this->assertEquals($importedEntity->getActionsConfiguration(), $this->entity->getActionsConfiguration()); + $this->assertEquals($importedEntity->getExcludeDefinitions(), $this->entity->getExcludeDefinitions()); $this->assertTrue($this->entity->isEnabled()); // enabled must not be changed } From 27d133bbd28444115fafc64653cc9ca7bfe98657 Mon Sep 17 00:00:00 2001 From: Ivan Shakuta Date: Tue, 2 Jun 2015 18:29:44 +0300 Subject: [PATCH 32/47] BAP-8336: Make extend entity OroTagBundle:Tagging - made tag entities extendable --- src/Oro/Bundle/TagBundle/Entity/Tag.php | 5 ++++- src/Oro/Bundle/TagBundle/Entity/Tagging.php | 5 ++++- src/Oro/Bundle/TagBundle/Model/ExtendTag.php | 17 +++++++++++++++++ .../Bundle/TagBundle/Model/ExtendTagging.php | 17 +++++++++++++++++ 4 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 src/Oro/Bundle/TagBundle/Model/ExtendTag.php create mode 100644 src/Oro/Bundle/TagBundle/Model/ExtendTagging.php diff --git a/src/Oro/Bundle/TagBundle/Entity/Tag.php b/src/Oro/Bundle/TagBundle/Entity/Tag.php index ab797ccb0b3..a5f3c4262f8 100644 --- a/src/Oro/Bundle/TagBundle/Entity/Tag.php +++ b/src/Oro/Bundle/TagBundle/Entity/Tag.php @@ -7,6 +7,7 @@ use Doctrine\Common\Collections\ArrayCollection; use Oro\Bundle\OrganizationBundle\Entity\Organization; +use Oro\Bundle\TagBundle\Model\ExtendTag; use Oro\Bundle\UserBundle\Entity\User; use Oro\Bundle\EntityConfigBundle\Metadata\Annotation\Config; use Oro\Bundle\EntityConfigBundle\Metadata\Annotation\ConfigField; @@ -45,7 +46,7 @@ * } * ) */ -class Tag +class Tag extends ExtendTag { /** * @var integer @@ -117,6 +118,8 @@ class Tag */ public function __construct($name = null) { + parent::__construct(); + $this->setName($name); $this->tagging = new ArrayCollection(); } diff --git a/src/Oro/Bundle/TagBundle/Entity/Tagging.php b/src/Oro/Bundle/TagBundle/Entity/Tagging.php index a51d8c1170d..60564362eee 100644 --- a/src/Oro/Bundle/TagBundle/Entity/Tagging.php +++ b/src/Oro/Bundle/TagBundle/Entity/Tagging.php @@ -5,6 +5,7 @@ use Doctrine\Common\Util\ClassUtils; use Doctrine\ORM\Mapping as ORM; +use Oro\Bundle\TagBundle\Model\ExtendTagging; use Oro\Bundle\UserBundle\Entity\User; use Oro\Bundle\EntityConfigBundle\Metadata\Annotation\Config; use Oro\Bundle\EntityConfigBundle\Metadata\Annotation\ConfigField; @@ -40,7 +41,7 @@ * } * ) */ -class Tagging +class Tagging extends ExtendTagging { /** * @var integer $id @@ -101,6 +102,8 @@ class Tagging */ public function __construct(Tag $tag = null, Taggable $resource = null) { + parent::__construct(); + if ($tag != null) { $this->setTag($tag); } diff --git a/src/Oro/Bundle/TagBundle/Model/ExtendTag.php b/src/Oro/Bundle/TagBundle/Model/ExtendTag.php new file mode 100644 index 00000000000..f5c7eca1464 --- /dev/null +++ b/src/Oro/Bundle/TagBundle/Model/ExtendTag.php @@ -0,0 +1,17 @@ + Date: Wed, 3 Jun 2015 12:15:39 +0300 Subject: [PATCH 33/47] BAP-8336: Make extend entity OroTagBundle:Tagging - fix CS (space at the end of line) --- src/Oro/Bundle/TagBundle/Model/ExtendTag.php | 2 +- src/Oro/Bundle/TagBundle/Model/ExtendTagging.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Oro/Bundle/TagBundle/Model/ExtendTag.php b/src/Oro/Bundle/TagBundle/Model/ExtendTag.php index f5c7eca1464..b739d4aaf7c 100644 --- a/src/Oro/Bundle/TagBundle/Model/ExtendTag.php +++ b/src/Oro/Bundle/TagBundle/Model/ExtendTag.php @@ -2,7 +2,7 @@ namespace Oro\Bundle\TagBundle\Model; -class ExtendTag +class ExtendTag { /** * Constructor diff --git a/src/Oro/Bundle/TagBundle/Model/ExtendTagging.php b/src/Oro/Bundle/TagBundle/Model/ExtendTagging.php index a9dcb57cc73..5b0272d10f1 100644 --- a/src/Oro/Bundle/TagBundle/Model/ExtendTagging.php +++ b/src/Oro/Bundle/TagBundle/Model/ExtendTagging.php @@ -2,7 +2,7 @@ namespace Oro\Bundle\TagBundle\Model; -class ExtendTagging +class ExtendTagging { /** * Constructor From 76d0b5ba720a4739ca2681a7951460c4cf7000a2 Mon Sep 17 00:00:00 2001 From: Roman Grebenchuk Date: Wed, 3 Jun 2015 18:26:27 +0300 Subject: [PATCH 34/47] BAP-8344: warning and failed selenium tests build - added additional checks to initParameter --- .../EntityConfigBundle/Provider/PropertyConfigContainer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Oro/Bundle/EntityConfigBundle/Provider/PropertyConfigContainer.php b/src/Oro/Bundle/EntityConfigBundle/Provider/PropertyConfigContainer.php index 18061324e30..7d01aa40754 100644 --- a/src/Oro/Bundle/EntityConfigBundle/Provider/PropertyConfigContainer.php +++ b/src/Oro/Bundle/EntityConfigBundle/Provider/PropertyConfigContainer.php @@ -362,7 +362,7 @@ public function initConfig($config) */ protected function initParameter($parameter) { - if ($this->container->has($parameter)) { + if (is_string($parameter) && $this->container->has($parameter)) { $callableService = $this->container->get($parameter); return call_user_func($callableService); From c31a0dd386a55e33fdef0f58188e9150c2fce85f Mon Sep 17 00:00:00 2001 From: Yurii Muratov Date: Mon, 8 Jun 2015 21:07:08 +0300 Subject: [PATCH 35/47] BAP-8323: Add check for email address in search query --- src/Oro/Bundle/SearchBundle/Engine/Orm/PdoMysql.php | 13 ++++++++++++- src/Oro/Bundle/SearchBundle/Query/Query.php | 2 +- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/Oro/Bundle/SearchBundle/Engine/Orm/PdoMysql.php b/src/Oro/Bundle/SearchBundle/Engine/Orm/PdoMysql.php index c22863a1a46..cf133873d34 100644 --- a/src/Oro/Bundle/SearchBundle/Engine/Orm/PdoMysql.php +++ b/src/Oro/Bundle/SearchBundle/Engine/Orm/PdoMysql.php @@ -88,7 +88,18 @@ protected function addTextField(QueryBuilder $qb, $index, $searchCondition, $set */ protected function getWords($value) { - return array_filter(explode(' ', $value)); + $results = array_filter(explode(' ', $value)); + $results = array_map( + function ($word) { + if (filter_var($word, FILTER_VALIDATE_EMAIL)) { + $word = sprintf('"%s"', $word); + } + + return $word; + }, + $results + ); + return $results; } /** diff --git a/src/Oro/Bundle/SearchBundle/Query/Query.php b/src/Oro/Bundle/SearchBundle/Query/Query.php index 614b360ab14..e46af31a84b 100644 --- a/src/Oro/Bundle/SearchBundle/Query/Query.php +++ b/src/Oro/Bundle/SearchBundle/Query/Query.php @@ -397,7 +397,7 @@ public static function clearString($inputString) preg_replace( '/ +/', self::DELIMITER, - preg_replace('/[^\w:*]/u', self::DELIMITER, $inputString) + preg_replace('/[^\w:*@.]/u', self::DELIMITER, $inputString) ) ); From 9429e2463c09209a56746d56147a803dd337137c Mon Sep 17 00:00:00 2001 From: Yurii Muratov Date: Mon, 8 Jun 2015 21:09:00 +0300 Subject: [PATCH 36/47] BAP-8323: Add check for email address in search query - fix cs --- .../SearchBundle/Engine/Orm/PdoMysql.php | 25 +++++++++++++------ 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/Oro/Bundle/SearchBundle/Engine/Orm/PdoMysql.php b/src/Oro/Bundle/SearchBundle/Engine/Orm/PdoMysql.php index cf133873d34..4599b125fc8 100644 --- a/src/Oro/Bundle/SearchBundle/Engine/Orm/PdoMysql.php +++ b/src/Oro/Bundle/SearchBundle/Engine/Orm/PdoMysql.php @@ -55,6 +55,7 @@ public static function getPlainSql() * @param integer $index * @param array $searchCondition * @param boolean $setOrderBy + * * @return string */ protected function addTextField(QueryBuilder $qb, $index, $searchCondition, $setOrderBy = true) @@ -63,7 +64,7 @@ protected function addTextField(QueryBuilder $qb, $index, $searchCondition, $set // TODO Need to clarify search requirements in scope of CRM-214 if ($searchCondition['condition'] == Query::OPERATOR_CONTAINS) { - $whereExpr = $this->createMatchAgainstWordsExpr($qb, $words, $index, $searchCondition, $setOrderBy); + $whereExpr = $this->createMatchAgainstWordsExpr($qb, $words, $index, $searchCondition, $setOrderBy); $shortWords = $this->getWordsLessThanFullTextMinWordLength($words); if ($shortWords) { $whereExpr = $qb->expr()->orX( @@ -84,6 +85,7 @@ protected function addTextField(QueryBuilder $qb, $index, $searchCondition, $set * Get array of words retrieved from $value string * * @param string $value + * * @return array */ protected function getWords($value) @@ -99,6 +101,7 @@ function ($word) { }, $results ); + return $results; } @@ -106,6 +109,7 @@ function ($word) { * Get words that have length less than $this->fullTextMinWordLength * * @param array $words + * * @return array */ protected function getWordsLessThanFullTextMinWordLength(array $words) @@ -132,7 +136,7 @@ function ($value) use ($length) { protected function getFullTextMinWordLength() { if (null === $this->fullTextMinWordLength) { - $this->fullTextMinWordLength = (int) $this->em->getConnection()->fetchColumn( + $this->fullTextMinWordLength = (int)$this->em->getConnection()->fetchColumn( "SHOW VARIABLES LIKE 'ft_min_word_len'", [], 1 @@ -151,6 +155,7 @@ protected function getFullTextMinWordLength() * @param string $index * @param array $searchCondition * @param bool $setOrderBy + * * @return string */ protected function createMatchAgainstWordsExpr( @@ -187,7 +192,7 @@ protected function createMatchAgainstWordsExpr( )->setParameter($rawValueParameter, $fieldValue)->orderBy('rankField', 'DESC'); } - return (string) $result; + return (string)$result; } /** @@ -196,8 +201,9 @@ protected function createMatchAgainstWordsExpr( * * @param QueryBuilder $qb * @param array $words - * @param $index - * @param array $searchCondition + * @param $index + * @param array $searchCondition + * * @return string */ protected function createLikeWordsExpr( @@ -218,18 +224,19 @@ protected function createLikeWordsExpr( } if ($this->isConcreteField($fieldName) && !$this->isAllDataField($fieldName)) { $fieldParameter = 'field' . $index; - $result = $qb->expr()->andX($result, "$joinAlias.field = :$fieldParameter"); + $result = $qb->expr()->andX($result, "$joinAlias.field = :$fieldParameter"); $qb->setParameter($fieldParameter, $fieldValue); } - return (string) $result; + return (string)$result; } /** * @param QueryBuilder $qb * @param int $index - * @param array $words, + * @param array $words , * @param array $searchCondition + * * @return string */ protected function createNotLikeWordsExpr( @@ -259,6 +266,7 @@ protected function createNotLikeWordsExpr( /** * @param array $fieldName + * * @return bool */ protected function isConcreteField($fieldName) @@ -268,6 +276,7 @@ protected function isConcreteField($fieldName) /** * @param array $fieldName + * * @return bool */ protected function isAllDataField($fieldName) From 07c9b5dfdb86d16653ad0b657e43ef7e28cae69f Mon Sep 17 00:00:00 2001 From: Yurii Muratov Date: Tue, 9 Jun 2015 18:48:29 +0300 Subject: [PATCH 37/47] BAP-8323: Add check for email address in search query - fix cs --- src/Oro/Bundle/SearchBundle/Engine/Orm/PdoMysql.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Oro/Bundle/SearchBundle/Engine/Orm/PdoMysql.php b/src/Oro/Bundle/SearchBundle/Engine/Orm/PdoMysql.php index 4599b125fc8..330531f2a28 100644 --- a/src/Oro/Bundle/SearchBundle/Engine/Orm/PdoMysql.php +++ b/src/Oro/Bundle/SearchBundle/Engine/Orm/PdoMysql.php @@ -234,7 +234,7 @@ protected function createLikeWordsExpr( /** * @param QueryBuilder $qb * @param int $index - * @param array $words , + * @param array $words * @param array $searchCondition * * @return string From 3af5b5ba0da2127f9f0bf6d5dc96b799b48f6ccd Mon Sep 17 00:00:00 2001 From: Yurii Muratov Date: Wed, 10 Jun 2015 11:40:45 +0300 Subject: [PATCH 38/47] BAP-8323: Add check for email address in search query - fix tests --- .../SearchBundle/Engine/Orm/PdoMysql.php | 12 ++-- .../Controller/requests/request#1.yml | 68 +------------------ .../Controller/requests/request#13.yml | 4 +- .../Controller/requests/request#14.yml | 2 +- 4 files changed, 13 insertions(+), 73 deletions(-) diff --git a/src/Oro/Bundle/SearchBundle/Engine/Orm/PdoMysql.php b/src/Oro/Bundle/SearchBundle/Engine/Orm/PdoMysql.php index 330531f2a28..2cb1f726832 100644 --- a/src/Oro/Bundle/SearchBundle/Engine/Orm/PdoMysql.php +++ b/src/Oro/Bundle/SearchBundle/Engine/Orm/PdoMysql.php @@ -60,7 +60,10 @@ public static function getPlainSql() */ protected function addTextField(QueryBuilder $qb, $index, $searchCondition, $setOrderBy = true) { - $words = $this->getWords($this->filterTextFieldValue($searchCondition['fieldValue'])); + $words = $this->getWords( + $this->filterTextFieldValue($searchCondition['fieldValue']), + $searchCondition['condition'] + ); // TODO Need to clarify search requirements in scope of CRM-214 if ($searchCondition['condition'] == Query::OPERATOR_CONTAINS) { @@ -85,15 +88,16 @@ protected function addTextField(QueryBuilder $qb, $index, $searchCondition, $set * Get array of words retrieved from $value string * * @param string $value + * @param string $searchCondition * * @return array */ - protected function getWords($value) + protected function getWords($value, $searchCondition) { $results = array_filter(explode(' ', $value)); $results = array_map( - function ($word) { - if (filter_var($word, FILTER_VALIDATE_EMAIL)) { + function ($word) use ($searchCondition) { + if ($searchCondition === Query::OPERATOR_CONTAINS && filter_var($word, FILTER_VALIDATE_EMAIL)) { $word = sprintf('"%s"', $word); } diff --git a/src/Oro/Bundle/SearchBundle/Tests/Functional/Controller/requests/request#1.yml b/src/Oro/Bundle/SearchBundle/Tests/Functional/Controller/requests/request#1.yml index 86e38315f7c..844fd88fb94 100644 --- a/src/Oro/Bundle/SearchBundle/Tests/Functional/Controller/requests/request#1.yml +++ b/src/Oro/Bundle/SearchBundle/Tests/Functional/Controller/requests/request#1.yml @@ -5,81 +5,17 @@ request: offset: ~ max_results: ~ response: - records_count: 9 - count: 9 + records_count: 1 + count: 1 rest: data: - entity_name: Oro\Bundle\TestFrameworkBundle\Entity\Item record_string: item9@mail.com record_url: http://localhost/search/ - - - entity_name: Oro\Bundle\TestFrameworkBundle\Entity\Item - record_string: item1@mail.com - record_url: http://localhost/search/ - - - entity_name: Oro\Bundle\TestFrameworkBundle\Entity\Item - record_string: item2@mail.com - record_url: http://localhost/search/ - - - entity_name: Oro\Bundle\TestFrameworkBundle\Entity\Item - record_string: item3@mail.com - record_url: http://localhost/search/ - - - entity_name: Oro\Bundle\TestFrameworkBundle\Entity\Item - record_string: item4@mail.com - record_url: http://localhost/search/ - - - entity_name: Oro\Bundle\TestFrameworkBundle\Entity\Item - record_string: item5@mail.com - record_url: http://localhost/search/ - - - entity_name: Oro\Bundle\TestFrameworkBundle\Entity\Item - record_string: item6@mail.com - record_url: http://localhost/search/ - - - entity_name: Oro\Bundle\TestFrameworkBundle\Entity\Item - record_string: item7@mail.com - record_url: http://localhost/search/ - - - entity_name: Oro\Bundle\TestFrameworkBundle\Entity\Item - record_string: item8@mail.com - record_url: http://localhost/search/ soap: item: - entityName: Oro\Bundle\TestFrameworkBundle\Entity\Item recordTitle: item9@mail.com recordUrl: http://localhost/search/ - - - entityName: Oro\Bundle\TestFrameworkBundle\Entity\Item - recordTitle: item1@mail.com - recordUrl: http://localhost/search/ - - - entityName: Oro\Bundle\TestFrameworkBundle\Entity\Item - recordTitle: item2@mail.com - recordUrl: http://localhost/search/ - - - entityName: Oro\Bundle\TestFrameworkBundle\Entity\Item - recordTitle: item3@mail.com - recordUrl: http://localhost/search/ - - - entityName: Oro\Bundle\TestFrameworkBundle\Entity\Item - recordTitle: item4@mail.com - recordUrl: http://localhost/search/ - - - entityName: Oro\Bundle\TestFrameworkBundle\Entity\Item - recordTitle: item5@mail.com - recordUrl: http://localhost/search/ - - - entityName: Oro\Bundle\TestFrameworkBundle\Entity\Item - recordTitle: item6@mail.com - recordUrl: http://localhost/search/ - - - entityName: Oro\Bundle\TestFrameworkBundle\Entity\Item - recordTitle: item7@mail.com - recordUrl: http://localhost/search/ - - - entityName: Oro\Bundle\TestFrameworkBundle\Entity\Item - recordTitle: item8@mail.com - recordUrl: http://localhost/search/ diff --git a/src/Oro/Bundle/SearchBundle/Tests/Functional/Controller/requests/request#13.yml b/src/Oro/Bundle/SearchBundle/Tests/Functional/Controller/requests/request#13.yml index 42116ddae8f..d8d850f33de 100644 --- a/src/Oro/Bundle/SearchBundle/Tests/Functional/Controller/requests/request#13.yml +++ b/src/Oro/Bundle/SearchBundle/Tests/Functional/Controller/requests/request#13.yml @@ -5,8 +5,8 @@ request: offset: 1 max_results: 3 response: - records_count: 9 - count: 3 + records_count: 1 + count: 0 rest: data: [] soap: diff --git a/src/Oro/Bundle/SearchBundle/Tests/Functional/Controller/requests/request#14.yml b/src/Oro/Bundle/SearchBundle/Tests/Functional/Controller/requests/request#14.yml index dd0ae357719..cbd28e2f00c 100644 --- a/src/Oro/Bundle/SearchBundle/Tests/Functional/Controller/requests/request#14.yml +++ b/src/Oro/Bundle/SearchBundle/Tests/Functional/Controller/requests/request#14.yml @@ -5,7 +5,7 @@ request: offset: 0 max_results: 1 response: - records_count: 9 + records_count: 1 count: 1 rest: data: From f288401c9dc5230eaaff86856a300639b9975c7f Mon Sep 17 00:00:00 2001 From: Yurii Muratov Date: Wed, 10 Jun 2015 20:03:55 +0300 Subject: [PATCH 39/47] BAP-7550: Add ACL checks for mass action delete --- .../Datasource/Orm/IterableResult.php | 6 ++--- .../MassAction/DeleteMassActionHandler.php | 23 ++++++++++++++----- .../MassAction/MassActionDispatcher.php | 22 +++++++++++++++--- .../Resources/config/mass_actions.yml | 2 ++ 4 files changed, 41 insertions(+), 12 deletions(-) diff --git a/src/Oro/Bundle/DataGridBundle/Datasource/Orm/IterableResult.php b/src/Oro/Bundle/DataGridBundle/Datasource/Orm/IterableResult.php index 6ffc9689582..4d0bba23b1e 100644 --- a/src/Oro/Bundle/DataGridBundle/Datasource/Orm/IterableResult.php +++ b/src/Oro/Bundle/DataGridBundle/Datasource/Orm/IterableResult.php @@ -14,7 +14,7 @@ class IterableResult extends BufferedQueryResultIterator implements IterableResultInterface { /** - * @var QueryBuilder + * @var QueryBuilder|Query */ private $source; @@ -28,9 +28,9 @@ class IterableResult extends BufferedQueryResultIterator implements IterableResu /** * Constructor * - * @param QueryBuilder $source + * @param QueryBuilder|Query $source */ - public function __construct(QueryBuilder $source) + public function __construct($source) { parent::__construct($source); $this->source = $source; diff --git a/src/Oro/Bundle/DataGridBundle/Extension/MassAction/DeleteMassActionHandler.php b/src/Oro/Bundle/DataGridBundle/Extension/MassAction/DeleteMassActionHandler.php index 279753fbb71..68a46faf313 100644 --- a/src/Oro/Bundle/DataGridBundle/Extension/MassAction/DeleteMassActionHandler.php +++ b/src/Oro/Bundle/DataGridBundle/Extension/MassAction/DeleteMassActionHandler.php @@ -9,6 +9,7 @@ use Oro\Bundle\DataGridBundle\Exception\LogicException; use Oro\Bundle\DataGridBundle\Datasource\ResultRecordInterface; use Oro\Bundle\DataGridBundle\Datasource\Orm\DeletionIterableResult; +use Oro\Bundle\SecurityBundle\SecurityFacade; class DeleteMassActionHandler implements MassActionHandlerInterface { @@ -24,6 +25,9 @@ class DeleteMassActionHandler implements MassActionHandlerInterface */ protected $translator; + /** @var SecurityFacade */ + protected $securityFacade; + /** * @var string */ @@ -32,11 +36,16 @@ class DeleteMassActionHandler implements MassActionHandlerInterface /** * @param EntityManager $entityManager * @param TranslatorInterface $translator + * @param SecurityFacade $securityFacade */ - public function __construct(EntityManager $entityManager, TranslatorInterface $translator) - { - $this->entityManager = $entityManager; - $this->translator = $translator; + public function __construct( + EntityManager $entityManager, + TranslatorInterface $translator, + SecurityFacade $securityFacade + ) { + $this->entityManager = $entityManager; + $this->translator = $translator; + $this->securityFacade = $securityFacade; } /** @@ -72,9 +81,11 @@ public function handle(MassActionHandlerArgs $args) } if ($entity) { - $this->entityManager->remove($entity); + if ($this->securityFacade->isGranted('DELETE', $entity)) { + $this->entityManager->remove($entity); + $iteration++; + } - $iteration++; if ($iteration % self::FLUSH_BATCH_SIZE == 0) { $this->finishBatch(); } diff --git a/src/Oro/Bundle/DataGridBundle/Extension/MassAction/MassActionDispatcher.php b/src/Oro/Bundle/DataGridBundle/Extension/MassAction/MassActionDispatcher.php index 8160d6f86ac..b07c2254204 100644 --- a/src/Oro/Bundle/DataGridBundle/Extension/MassAction/MassActionDispatcher.php +++ b/src/Oro/Bundle/DataGridBundle/Extension/MassAction/MassActionDispatcher.php @@ -2,12 +2,14 @@ namespace Oro\Bundle\DataGridBundle\Extension\MassAction; +use Doctrine\ORM\Query; use Doctrine\ORM\QueryBuilder; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\File\Exception\UnexpectedTypeException; use Symfony\Component\HttpFoundation\Request; +use Oro\Bundle\DataGridBundle\Datagrid\Builder; use Oro\Bundle\DataGridBundle\Datagrid\Manager; use Oro\Bundle\DataGridBundle\Datagrid\DatagridInterface; use Oro\Bundle\DataGridBundle\Datasource\Orm\IterableResult; @@ -16,6 +18,7 @@ use Oro\Bundle\DataGridBundle\Extension\ExtensionVisitorInterface; use Oro\Bundle\DataGridBundle\Extension\MassAction\Actions\MassActionInterface; use Oro\Bundle\FilterBundle\Grid\Extension\OrmFilterExtension; +use Oro\Bundle\SecurityBundle\ORM\Walker\AclHelper; class MassActionDispatcher { @@ -29,10 +32,19 @@ class MassActionDispatcher */ protected $manager; - public function __construct(ContainerInterface $container, Manager $manager) + /** @var AclHelper */ + protected $aclHelper; + + /** + * @param ContainerInterface $container + * @param Manager $manager + * @param AclHelper $aclHelper + */ + public function __construct(ContainerInterface $container, Manager $manager, AclHelper $aclHelper) { $this->container = $container; $this->manager = $manager; + $this->aclHelper = $aclHelper; } /** @@ -98,6 +110,10 @@ public function dispatch($datagridName, $actionName, array $parameters, array $d //prepare query builder $qb->setMaxResults(null); + if (!$datagrid->getConfig()->offsetGetByPath(Builder::DATASOURCE_SKIP_ACL_CHECK, false)) { + $qb = $this->aclHelper->apply($qb); + } + $resultIterator = $this->getResultIterator($qb); $handlerArgs = new MassActionHandlerArgs($massAction, $datagrid, $resultIterator, $data); @@ -174,12 +190,12 @@ function (ExtensionVisitorInterface $extension) { } /** - * @param QueryBuilder $qb + * @param QueryBuilder|Query $qb * @param null $bufferSize * * @return IterableResult */ - protected function getResultIterator(QueryBuilder $qb, $bufferSize = null) + protected function getResultIterator($qb, $bufferSize = null) { $result = new IterableResult($qb); diff --git a/src/Oro/Bundle/DataGridBundle/Resources/config/mass_actions.yml b/src/Oro/Bundle/DataGridBundle/Resources/config/mass_actions.yml index 9999d603632..0bdf7e740eb 100644 --- a/src/Oro/Bundle/DataGridBundle/Resources/config/mass_actions.yml +++ b/src/Oro/Bundle/DataGridBundle/Resources/config/mass_actions.yml @@ -14,6 +14,7 @@ services: arguments: - @doctrine.orm.entity_manager - @translator + - @oro_security.security_facade oro_datagrid.mass_action.parameters_parser: class: %oro_datagrid.mass_action.parameters_parser.class% @@ -23,6 +24,7 @@ services: arguments: - @service_container - @oro_datagrid.datagrid.manager + - @oro_security.acl_helper oro_datagrid.extension.mass_action.type.ajax: class: %oro_datagrid.extension.mass_action.type.ajax.class% From 05f10bc5aa49205e957ad0425a1004be5fb3c11e Mon Sep 17 00:00:00 2001 From: Yurii Muratov Date: Thu, 11 Jun 2015 12:56:03 +0300 Subject: [PATCH 40/47] CRM-3336: Fix count query on postgresql --- src/Oro/Bundle/TrackingBundle/Processor/TrackingProcessor.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Oro/Bundle/TrackingBundle/Processor/TrackingProcessor.php b/src/Oro/Bundle/TrackingBundle/Processor/TrackingProcessor.php index 96859fd2e8c..057bd35788a 100644 --- a/src/Oro/Bundle/TrackingBundle/Processor/TrackingProcessor.php +++ b/src/Oro/Bundle/TrackingBundle/Processor/TrackingProcessor.php @@ -240,7 +240,6 @@ protected function getIdentifyPrevVisitsCount() ->where('entity.identifierDetected = false') ->andWhere('entity.parsedUID > 0') ->andWhere('entity.parsingCount < :maxRetries') - ->orderBy('entity.firstActionTime', 'ASC') ->setParameter('maxRetries', self::MAX_RETRIES); if (count($this->skipList)) { From 4ac997d48291c93ac4b16397041060a10e7eee4e Mon Sep 17 00:00:00 2001 From: dmitrosh Date: Thu, 11 Jun 2015 13:17:00 +0300 Subject: [PATCH 41/47] BAP-8390: using data-ftid attribute of input instead id that contains unique postfix --- .../FormBundle/Resources/public/js/validator/repeated.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Oro/Bundle/FormBundle/Resources/public/js/validator/repeated.js b/src/Oro/Bundle/FormBundle/Resources/public/js/validator/repeated.js index e2df255c161..c0d1bb77cda 100644 --- a/src/Oro/Bundle/FormBundle/Resources/public/js/validator/repeated.js +++ b/src/Oro/Bundle/FormBundle/Resources/public/js/validator/repeated.js @@ -16,9 +16,12 @@ define(['jquery', 'underscore', 'orotranslation/js/translator', 'jquery.validate 'Repeated', function (value, element, params) { // validator should be added to repeated field (second one) - var id = element.id.slice(0, -(params.second_name || '').length) + (params.first_name || ''), - firstElement = document.getElementById(id); - return this.optional(firstElement) || value === this.elementValue(firstElement); + var attr = element.hasAttribute('data-ftid') ? 'data-ftid' : 'id', + id = element.getAttribute(attr), + secondName = params.second_name || '', + firstId = id.slice(0, -secondName.length) + (params.first_name || ''), + firstElement = document.querySelector('[' + attr + '="' + firstId + '"]'); + return firstElement && (this.optional(firstElement) || value === this.elementValue(firstElement)); }, function (param) { param = _.extend({}, defaultParam, param); From f9ec49183b799dd10eb3da48a679029aa00d3149 Mon Sep 17 00:00:00 2001 From: Valentine Velikiy Date: Wed, 3 Jun 2015 20:03:08 +0300 Subject: [PATCH 42/47] CRM-3417: Add step for customer creation based on email for guest orders --- .../ImportExportBundle/Field/DatabaseHelper.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/Oro/Bundle/ImportExportBundle/Field/DatabaseHelper.php b/src/Oro/Bundle/ImportExportBundle/Field/DatabaseHelper.php index 1acc4d174c3..0c4b72e4d5a 100644 --- a/src/Oro/Bundle/ImportExportBundle/Field/DatabaseHelper.php +++ b/src/Oro/Bundle/ImportExportBundle/Field/DatabaseHelper.php @@ -274,4 +274,15 @@ protected function shouldBeAddedOrganizationLimits($entityName) return $this->securityFacadeLink->getService()->getOrganization() && $this->ownershipMetadataProviderLink->getService()->getMetadata($entityName)->getOrganizationFieldName(); } + + /** + * @param $entity + */ + public function persist($entity) + { + $entityName = ClassUtils::getClass($entity); + /** @var EntityManager $entityManager */ + $entityManager = $this->registry->getManagerForClass($entityName); + $entityManager->persist($entity); + } } From 04b2c4c2d1c0b8f1074bf110ef125b707813cc3d Mon Sep 17 00:00:00 2001 From: Valentine Velikiy Date: Thu, 4 Jun 2015 13:59:02 +0300 Subject: [PATCH 43/47] CRM-3417: Add step for customer creation based on email for guest orders --- src/Oro/Bundle/ImportExportBundle/Field/DatabaseHelper.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Oro/Bundle/ImportExportBundle/Field/DatabaseHelper.php b/src/Oro/Bundle/ImportExportBundle/Field/DatabaseHelper.php index 0c4b72e4d5a..c011ee49e3f 100644 --- a/src/Oro/Bundle/ImportExportBundle/Field/DatabaseHelper.php +++ b/src/Oro/Bundle/ImportExportBundle/Field/DatabaseHelper.php @@ -85,7 +85,7 @@ public function findOneBy($entityName, array $criteria) $storageKey = serialize($serializationCriteria); - if (empty($this->entities[$entityName]) || !array_key_exists($storageKey, $this->entities[$entityName])) { + if (empty($this->entities[$entityName]) || empty($this->entities[$entityName][$storageKey])) { /** @var EntityRepository $entityRepository */ $entityRepository = $this->registry->getRepository($entityName); $queryBuilder = $entityRepository->createQueryBuilder('e') @@ -284,5 +284,6 @@ public function persist($entity) /** @var EntityManager $entityManager */ $entityManager = $this->registry->getManagerForClass($entityName); $entityManager->persist($entity); + $entityManager->flush($entity); } } From bb52f6d13bd24df86a19d2a665d1a91d7e83c93f Mon Sep 17 00:00:00 2001 From: Makar Sichevoy Date: Fri, 5 Jun 2015 19:10:45 +0300 Subject: [PATCH 44/47] CRM-3417 --- .../ImportExportBundle/Field/DatabaseHelper.php | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/Oro/Bundle/ImportExportBundle/Field/DatabaseHelper.php b/src/Oro/Bundle/ImportExportBundle/Field/DatabaseHelper.php index c011ee49e3f..0db7e21c10f 100644 --- a/src/Oro/Bundle/ImportExportBundle/Field/DatabaseHelper.php +++ b/src/Oro/Bundle/ImportExportBundle/Field/DatabaseHelper.php @@ -275,15 +275,8 @@ protected function shouldBeAddedOrganizationLimits($entityName) && $this->ownershipMetadataProviderLink->getService()->getMetadata($entityName)->getOrganizationFieldName(); } - /** - * @param $entity - */ - public function persist($entity) + public function getRegistry() { - $entityName = ClassUtils::getClass($entity); - /** @var EntityManager $entityManager */ - $entityManager = $this->registry->getManagerForClass($entityName); - $entityManager->persist($entity); - $entityManager->flush($entity); + return $this->registry; } } From a13fa1fbae42d41ca19bf4df430cc331eacabd18 Mon Sep 17 00:00:00 2001 From: Vova Soroka Date: Thu, 11 Jun 2015 17:38:53 +0300 Subject: [PATCH 45/47] BAP-3621: Add foreign keys for extended relation fields --- .../Tools/CommandExecutor.php | 13 +++- .../Command/UpdateSchemaCommand.php | 12 ++++ .../Extend/EntityProcessor.php | 8 ++- ...tendSchemaUpdateRemoveNamespacedAssets.php | 65 +++++++++++++++++++ .../WorkflowBundle/Field/FieldGenerator.php | 8 +-- 5 files changed, 98 insertions(+), 8 deletions(-) create mode 100644 src/Oro/Bundle/EntityExtendBundle/Tools/ExtendSchemaUpdateRemoveNamespacedAssets.php diff --git a/src/Oro/Bundle/EntityConfigBundle/Tools/CommandExecutor.php b/src/Oro/Bundle/EntityConfigBundle/Tools/CommandExecutor.php index 3f4a586f36e..b89f2538fef 100644 --- a/src/Oro/Bundle/EntityConfigBundle/Tools/CommandExecutor.php +++ b/src/Oro/Bundle/EntityConfigBundle/Tools/CommandExecutor.php @@ -60,13 +60,18 @@ public function __construct( * in seconds. Default timeout is 300 seconds. * If '--ignore-errors' parameter is specified any errors are ignored; * otherwise, an exception is raises if an error happened. + * If '--disable-cache-sync' parameter is specified a synchronization of caches between current + * process and its child processes are disabled. * * @param string $command * @param array $params * @param LoggerInterface|null $logger * * @return integer The exit status code + * * @throws \RuntimeException if command failed and '--ignore-errors' parameter is not specified + * + * @SuppressWarnings(PHPMD.NPathComplexity) */ public function runCommand($command, $params = [], LoggerInterface $logger = null) { @@ -97,6 +102,12 @@ public function runCommand($command, $params = [], LoggerInterface $logger = nul $pb->setTimeout($this->defaultTimeout); } + $disableCacheSync = false; + if (array_key_exists('--disable-cache-sync', $params)) { + $disableCacheSync = $params['--disable-cache-sync']; + unset($params['--disable-cache-sync']); + } + foreach ($params as $name => $val) { $this->processParameter($pb, $name, $val); } @@ -119,7 +130,7 @@ function ($type, $data) use ($logger) { ); // synchronize all data caches - if ($this->dataCacheManager) { + if ($this->dataCacheManager && !$disableCacheSync) { $this->dataCacheManager->sync(); } diff --git a/src/Oro/Bundle/EntityExtendBundle/Command/UpdateSchemaCommand.php b/src/Oro/Bundle/EntityExtendBundle/Command/UpdateSchemaCommand.php index 3a37c16b616..d667730f6a2 100644 --- a/src/Oro/Bundle/EntityExtendBundle/Command/UpdateSchemaCommand.php +++ b/src/Oro/Bundle/EntityExtendBundle/Command/UpdateSchemaCommand.php @@ -41,12 +41,23 @@ public function configure() * * @param InputInterface $input * @param OutputInterface $output + * * @return int|null|void */ public function execute(InputInterface $input, OutputInterface $output) { $output->writeln($this->getDescription()); + /** + * Unfortunately due a poor design of the Doctrine\ORM\Tools\SchemaTool::getSchemaFromMetadata + * we have to use "class_alias" to replace "Doctrine\DBAL\Schema\Visitor\RemoveNamespacedAssets" + * with "Oro\Bundle\EntityExtendBundle\Tools\ExtendSchemaUpdateRemoveNamespacedAssets". + */ + class_alias( + 'Oro\Bundle\EntityExtendBundle\Tools\ExtendSchemaUpdateRemoveNamespacedAssets', + 'Doctrine\DBAL\Schema\Visitor\RemoveNamespacedAssets' + ); + /** @var EntityManager $em */ $em = $this->getContainer()->get('doctrine.orm.entity_manager'); /** @var ConfigManager $configManager */ @@ -89,6 +100,7 @@ function ($doctrineMetadata) use ($configManager) { /** * @param string $className * @param ConfigManager $configManager + * * @return bool */ protected function isExtendEntity($className, ConfigManager $configManager) diff --git a/src/Oro/Bundle/EntityExtendBundle/Extend/EntityProcessor.php b/src/Oro/Bundle/EntityExtendBundle/Extend/EntityProcessor.php index 883530ca85d..ff6125ac7fa 100644 --- a/src/Oro/Bundle/EntityExtendBundle/Extend/EntityProcessor.php +++ b/src/Oro/Bundle/EntityExtendBundle/Extend/EntityProcessor.php @@ -34,10 +34,14 @@ class EntityProcessor /** * @var array + * + * Disable sync caches for doctrine related commands + * because in other case entity classes and Doctrine metadata do not match each other + * and as result DoctrineDataCollector raises an exception */ protected $commands = [ - 'oro:entity-extend:update-config' => [], - 'oro:entity-extend:update-schema' => [], + 'oro:entity-extend:update-config' => ['--disable-cache-sync' => true], + 'oro:entity-extend:update-schema' => ['--disable-cache-sync' => true] ]; /** diff --git a/src/Oro/Bundle/EntityExtendBundle/Tools/ExtendSchemaUpdateRemoveNamespacedAssets.php b/src/Oro/Bundle/EntityExtendBundle/Tools/ExtendSchemaUpdateRemoveNamespacedAssets.php new file mode 100644 index 00000000000..06f7bb93aa9 --- /dev/null +++ b/src/Oro/Bundle/EntityExtendBundle/Tools/ExtendSchemaUpdateRemoveNamespacedAssets.php @@ -0,0 +1,65 @@ +schema = $schema; + } + + /** + * {@inheritdoc} + */ + public function acceptTable(Table $table) + { + if (!$table->isInDefaultNamespace($this->schema->getName())) { + $this->schema->dropTable($table->getName()); + } + } + + /** + * {@inheritdoc} + */ + public function acceptSequence(Sequence $sequence) + { + if (!$sequence->isInDefaultNamespace($this->schema->getName())) { + $this->schema->dropSequence($sequence->getName()); + } + } + + + /** + * {@inheritdoc} + */ + public function acceptForeignKey(Table $localTable, ForeignKeyConstraint $fkConstraint) + { + // do nothing here + // we do not need to remove any foreign keys because extended entities can reference to regular entities + } +} diff --git a/src/Oro/Bundle/WorkflowBundle/Field/FieldGenerator.php b/src/Oro/Bundle/WorkflowBundle/Field/FieldGenerator.php index 792a6a70b3c..1239000841f 100644 --- a/src/Oro/Bundle/WorkflowBundle/Field/FieldGenerator.php +++ b/src/Oro/Bundle/WorkflowBundle/Field/FieldGenerator.php @@ -98,18 +98,16 @@ public function generateWorkflowFields($entityClass) // update database $this->entityProcessor->updateDatabase(); - // make fields hidden + // make workflowItem field hidden // TODO: Fields can be hidden only after schema update due to a bug in DoctrineSubscriber - // TODO: Should be fixed in scope of https://magecore.atlassian.net/browse/BAP-3621 + // TODO: I'm not sure that the bug in DoctrineSubscriber. It seems that the bug in + // TODO: Doctrine\ORM\Tools\SchemaTool::getSchemaFromMetadata. See fix made in BAP-3621 // TODO: If make fields hidden then these fields will be created only for the first extended entity // TODO: Should be fixed in scope of https://magecore.atlassian.net/browse/BAP-3632 /* if (!$hasWorkflowItemField) { $this->hideRelationField($entityClass, self::PROPERTY_WORKFLOW_ITEM); } - if (!$hasWorkflowStepField) { - $this->hideRelationField($entityClass, self::PROPERTY_WORKFLOW_STEP); - } $this->configManager->flush(); */ } From ea9c14ac72bb7a6460b2ca620e978dcd4c43de3c Mon Sep 17 00:00:00 2001 From: Alexander Nezdoiminoga Date: Thu, 11 Jun 2015 16:55:33 +0300 Subject: [PATCH 46/47] BAP-8138: fix Impossible to build report chart by date --- .../Resources/config/services.yml | 6 +- .../Controller/ReportController.php | 85 +++++++++++++++---- 2 files changed, 70 insertions(+), 21 deletions(-) diff --git a/src/Oro/Bundle/DashboardBundle/Resources/config/services.yml b/src/Oro/Bundle/DashboardBundle/Resources/config/services.yml index e42b87750a5..1ddcfe42ac5 100644 --- a/src/Oro/Bundle/DashboardBundle/Resources/config/services.yml +++ b/src/Oro/Bundle/DashboardBundle/Resources/config/services.yml @@ -14,7 +14,7 @@ parameters: oro_dashboard.form.type.select.class: Oro\Bundle\DashboardBundle\Form\Type\DashboardSelectType oro_dashboard.provider.widget_configuration_form_provider.class: Oro\Bundle\DashboardBundle\Provider\WidgetConfigurationFormProvider oro_dashboard.widget_config_value.provider.class: Oro\Bundle\DashboardBundle\Provider\ConfigValueProvider - oro_dashboard.datetime.hepler.class: Oro\Bundle\DashboardBundle\Helper\DateHelper + oro_dashboard.datetime.helper.class: Oro\Bundle\DashboardBundle\Helper\DateHelper oro_dashboard.event_listener.widget_configuration_load.class: Oro\Bundle\DashboardBundle\EventListener\WidgetConfigurationLoadListener oro_dashboard.widget_config_value.date_range.converter.class: Oro\Bundle\DashboardBundle\Provider\Converters\FilterDateTimeRangeConverter @@ -104,8 +104,8 @@ services: - @form.factory - @oro_form.validator.constraint_factory - oro_dashboard.datetime.hepler: - class: %oro_dashboard.datetime.hepler.class% + oro_dashboard.datetime.helper: + class: %oro_dashboard.datetime.helper.class% arguments: - @oro_locale.settings - @doctrine diff --git a/src/Oro/Bundle/ReportBundle/Controller/ReportController.php b/src/Oro/Bundle/ReportBundle/Controller/ReportController.php index 1864bc139c6..4a54709b8b9 100644 --- a/src/Oro/Bundle/ReportBundle/Controller/ReportController.php +++ b/src/Oro/Bundle/ReportBundle/Controller/ReportController.php @@ -2,11 +2,15 @@ namespace Oro\Bundle\ReportBundle\Controller; +use Doctrine\DBAL\Types\Type; + use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; use Symfony\Bundle\FrameworkBundle\Controller\Controller; +use Oro\Bundle\DashboardBundle\Helper\DateHelper; +use Oro\Bundle\DataGridBundle\Datagrid\DatagridInterface; use Oro\Bundle\DataGridBundle\Extension\Pager\PagerInterface; use Oro\Bundle\ReportBundle\Entity\Report; use Oro\Bundle\ReportBundle\Entity\ReportType; @@ -31,7 +35,7 @@ public function viewAction(Report $entity) $reportGroup = $this->get('oro_entity_config.provider.entity') ->getConfig($entity->getEntity()) ->get('plural_label'); - $parameters = [ + $parameters = [ 'entity' => $entity, 'reportGroup' => $reportGroup ]; @@ -43,20 +47,19 @@ public function viewAction(Report $entity) if ($this->get('oro_report.datagrid.configuration.provider')->isReportValid($gridName)) { $parameters['gridName'] = $gridName; - $datagrid = $this->get('oro_datagrid.datagrid.manager') - ->getDatagrid( - $gridName, - [PagerInterface::PAGER_ROOT_PARAM => [PagerInterface::DISABLED_PARAM => true]] - ); + $datagrid = $this->get('oro_datagrid.datagrid.manager')->getDatagrid( + $gridName, + [PagerInterface::PAGER_ROOT_PARAM => [PagerInterface::DISABLED_PARAM => true]] + ); - $chartOptions = $this - ->get('oro_chart.options_builder') - ->buildOptions( - $entity->getChartOptions(), - $datagrid->getConfig()->toArray() - ); + $chartOptions = $this->get('oro_chart.options_builder')->buildOptions( + $entity->getChartOptions(), + $datagrid->getConfig()->toArray() + ); if (!empty($chartOptions)) { + $chartOptions = $this->processChartOptions($datagrid, $chartOptions); + $parameters['chartView'] = $this->get('oro_chart.view_builder') ->setDataGrid($datagrid) ->setOptions($chartOptions) @@ -115,7 +118,7 @@ public function updateAction(Report $entity) */ public function indexAction() { - return array(); + return []; } /** @@ -133,16 +136,16 @@ protected function update(Report $entity) return $this->get('oro_ui.router')->redirectAfterSave( [ - 'route' => 'oro_report_update', + 'route' => 'oro_report_update', 'parameters' => [ - 'id' => $entity->getId(), + 'id' => $entity->getId(), '_enableContentProviders' => 'mainMenu' ] ], [ - 'route' => 'oro_report_view', + 'route' => 'oro_report_view', 'parameters' => [ - 'id' => $entity->getId(), + 'id' => $entity->getId(), '_enableContentProviders' => 'mainMenu' ] ], @@ -150,11 +153,57 @@ protected function update(Report $entity) ); } - return array( + return [ 'entity' => $entity, 'form' => $this->get('oro_report.form.report')->createView(), 'entities' => $this->get('oro_report.entity_provider')->getEntities(), 'metadata' => $this->get('oro_query_designer.query_designer.manager')->getMetadata('report') + ]; + } + + /** + * Method detects type of report's chart 'label' field, and in case of datetime will check dates interval and + * set proper type (time, day, date, month or year). Xaxis labels not taken into account - they will be rendered + * automatically by flotr2. Also chart dot labels may overlap if dates are close to each other. + * + * Should be refactored in scope of BAP-8294. + * + * @param DatagridInterface $datagrid + * @param array $chartOptions + * + * @return array + */ + protected function processChartOptions(DatagridInterface $datagrid, array $chartOptions) + { + $labelFieldName = $chartOptions['data_schema']['label']; + $labelFieldType = $datagrid->getConfig()->offsetGetByPath( + sprintf('[columns][%s][frontend_type]', $labelFieldName) ); + + /** @var DateHelper $dateTimeHelper */ + $dateTimeHelper = $this->get('oro_dashboard.datetime.helper'); + $dateTypes = [Type::DATETIME, Type::DATE, Type::DATETIMETZ]; + + if (in_array($labelFieldType, $dateTypes)) { + $data = $datagrid->getData()->offsetGet('data'); + $dates = array_map( + function ($dataItem) use ($labelFieldName) { + return $dataItem[$labelFieldName]; + }, + $data + ); + + $minDate = new \DateTime(min($dates)); + $maxDate = new \DateTime(max($dates)); + + $formatStrings = $dateTimeHelper->getFormatStrings($minDate, $maxDate); + + $chartOptions['data_schema']['label'] = [ + 'field_name' => $chartOptions['data_schema']['label'], + 'type' => $formatStrings['viewType'] + ]; + } + + return $chartOptions; } } From d698cc0a2565988bbeccb5f62a1010458941c8be Mon Sep 17 00:00:00 2001 From: Alexander Nezdoiminoga Date: Thu, 11 Jun 2015 17:16:56 +0300 Subject: [PATCH 47/47] BAP-8138: fix Impossible to build report chart by date --- src/Oro/Bundle/ReportBundle/Controller/ReportController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Oro/Bundle/ReportBundle/Controller/ReportController.php b/src/Oro/Bundle/ReportBundle/Controller/ReportController.php index 4a54709b8b9..1f3a4882b2e 100644 --- a/src/Oro/Bundle/ReportBundle/Controller/ReportController.php +++ b/src/Oro/Bundle/ReportBundle/Controller/ReportController.php @@ -164,7 +164,7 @@ protected function update(Report $entity) /** * Method detects type of report's chart 'label' field, and in case of datetime will check dates interval and * set proper type (time, day, date, month or year). Xaxis labels not taken into account - they will be rendered - * automatically by flotr2. Also chart dot labels may overlap if dates are close to each other. + * automatically. Also chart dot labels may overlap if dates are close to each other. * * Should be refactored in scope of BAP-8294. *