├── tests ├── data │ └── hubdb.csv ├── Integration │ ├── Resources │ │ ├── CrmPipelinesDealsTest.php │ │ ├── CrmPipelinesTicketsTest.php │ │ ├── CompanyPropertyGroupsTest.php │ │ ├── DealPropertyGroupsTest.php │ │ ├── ContactPropertyGroupsTest.php │ │ ├── DealPropertiesTest.php │ │ ├── CompanyPropertiesTest.php │ │ ├── ContactPropertiesTest.php │ │ ├── ObjectPropertyGroupsTest.php │ │ ├── ObjectPropertiesTest.php │ │ ├── IntegrationTest.php │ │ ├── EventsTest.php │ │ ├── BlogsTest.php │ │ ├── OwnersTest.php │ │ ├── EmailSubscriptionTest.php │ │ ├── TimelineEventTypeProprtyTest.php │ │ ├── AnalyticsTest.php │ │ ├── TimelineEventTypeTest.php │ │ ├── EmailEventsTest.php │ │ ├── PagesTest.php │ │ ├── KeywordsTest.php │ │ ├── ContactDinamicListsTest.php │ │ ├── ContactListsTest.php │ │ ├── HubDBTest.php │ │ ├── DealPipelinesTest.php │ │ ├── BlogCommentsTest.php │ │ ├── BlogAuthorsTest.php │ │ ├── BlogTopicsTest.php │ │ ├── HubDBRowTest.php │ │ ├── CalendarEventsTest.php │ │ ├── EngagementsTest.php │ │ ├── FormsTest.php │ │ └── ProductsTest.php │ └── Abstraction │ │ ├── ProductData.php │ │ ├── EntityTestCase.php │ │ ├── DefaultTestCase.php │ │ ├── TimelineWithProprtyTestCase.php │ │ ├── HubDBRowTestCase.php │ │ ├── BlogPostTestCase.php │ │ ├── TimelineTestCase.php │ │ ├── ContactListsTestCase.php │ │ ├── PropertiesTestCase.php │ │ ├── PropertyGroupsTestCase.php │ │ └── CrmPipelinesTestCase.php ├── spec │ ├── Resources │ │ ├── BlogsSpec.php │ │ ├── FilesSpec.php │ │ ├── FormsSpec.php │ │ ├── PagesSpec.php │ │ ├── EventsSpec.php │ │ ├── AnalyticsSpec.php │ │ ├── BlogPostsSpec.php │ │ ├── KeywordsSpec.php │ │ ├── WorkflowsSpec.php │ │ ├── BlogTopicsSpec.php │ │ ├── BlogAuthorsSpec.php │ │ ├── ContactListsSpec.php │ │ ├── EmailEventsSpec.php │ │ ├── SocialMediaSpec.php │ │ ├── ContactPropertiesSpec.php │ │ ├── EmailSubscriptionSpec.php │ │ ├── CompaniesSpec.php │ │ ├── DealPropertiesSpec.php │ │ ├── CompanyPropertiesSpec.php │ │ └── ContactsSpec.php │ └── FactorySpec.php ├── Helpers │ └── SendsRequests.php └── unit │ ├── Utils │ ├── OAuth2Test.php │ └── WebhooksTest.php │ ├── Exception │ └── HubspotExceptionTest.php │ └── Support │ └── QueryBuilderTest.php ├── phpspec.sh ├── src ├── Exceptions │ ├── BadRequest.php │ ├── InvalidArgument.php │ └── HubspotException.php ├── Utils.php ├── Utils │ ├── Webhooks.php │ └── OAuth2.php ├── Delay.php ├── Resources │ ├── Resource.php │ ├── Integration.php │ ├── TransactionalEmail.php │ ├── Events.php │ ├── Keywords.php │ ├── Owners.php │ ├── Blogs.php │ ├── SocialMedia.php │ ├── BlogComments.php │ ├── DealPipelines.php │ ├── Tickets.php │ ├── Webhooks.php │ ├── CrmPipelines.php │ ├── EmailSubscription.php │ ├── EmailEvents.php │ ├── BlogAuthors.php │ ├── OAuth2.php │ ├── BlogTopics.php │ ├── Workflows.php │ ├── CrmAssociations.php │ ├── Products.php │ ├── CompanyProperties.php │ ├── LineItems.php │ └── ObjectProperties.php ├── helpers.php └── RetryMiddlewareFactory.php ├── phpspec.yml ├── .gitignore ├── .php-cs-fixer.dist.php ├── .travis.yml ├── phpunit.xml ├── composer.json ├── CONTRIBUTING.md └── CHANGELOG.md /tests/data/hubdb.csv: -------------------------------------------------------------------------------- 1 | Name;Count;;;; 2 | The first record;10;;;; 3 | The second record;14;;;; 4 | -------------------------------------------------------------------------------- /phpspec.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | if [ "${PHPSPEC}" != "false" ]; then 3 | vendor/bin/phpspec run --verbose 4 | fi 5 | -------------------------------------------------------------------------------- /src/Exceptions/BadRequest.php: -------------------------------------------------------------------------------- 1 | in([__DIR__]) 5 | ->exclude(['vendor', 'var']) 6 | ->notPath('/cache/') 7 | ; 8 | 9 | $config = new PhpCsFixer\Config(); 10 | return $config 11 | ->setFinder($finder) 12 | ->setRules([ 13 | '@PSR2' => true, 14 | '@PhpCsFixer' => true, 15 | ]) 16 | ; 17 | -------------------------------------------------------------------------------- /tests/Integration/Resources/CrmPipelinesTicketsTest.php: -------------------------------------------------------------------------------- 1 | beConstructedWith('demo', $client); 13 | } 14 | 15 | public function it_is_initializable() 16 | { 17 | $this->shouldHaveType('SevenShores\Hubspot\Resources\Blogs'); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/spec/Resources/FilesSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith('demo', $client); 13 | } 14 | 15 | public function it_is_initializable() 16 | { 17 | $this->shouldHaveType('SevenShores\Hubspot\Resources\Files'); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/spec/Resources/FormsSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith('demo', $client); 13 | } 14 | 15 | public function it_is_initializable() 16 | { 17 | $this->shouldHaveType('SevenShores\Hubspot\Resources\Forms'); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/spec/Resources/PagesSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith('demo', $client); 13 | } 14 | 15 | public function it_is_initializable() 16 | { 17 | $this->shouldHaveType('SevenShores\Hubspot\Resources\Pages'); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/spec/Resources/EventsSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith('demo', $client); 13 | } 14 | 15 | public function it_is_initializable() 16 | { 17 | $this->shouldHaveType('SevenShores\Hubspot\Resources\Events'); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/spec/Resources/AnalyticsSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith('demo', $client); 13 | } 14 | 15 | public function it_is_initializable() 16 | { 17 | $this->shouldHaveType('SevenShores\Hubspot\Resources\Analytics'); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/spec/Resources/BlogPostsSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith('demo', $client); 13 | } 14 | 15 | public function it_is_initializable() 16 | { 17 | $this->shouldHaveType('SevenShores\Hubspot\Resources\BlogPosts'); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/spec/Resources/KeywordsSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith('demo', $client); 13 | } 14 | 15 | public function it_is_initializable() 16 | { 17 | $this->shouldHaveType('SevenShores\Hubspot\Resources\Keywords'); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/spec/Resources/WorkflowsSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith('demo', $client); 13 | } 14 | 15 | public function it_is_initializable() 16 | { 17 | $this->shouldHaveType('SevenShores\Hubspot\Resources\Workflows'); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/spec/Resources/BlogTopicsSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith('demo', $client); 13 | } 14 | 15 | public function it_is_initializable() 16 | { 17 | $this->shouldHaveType('SevenShores\Hubspot\Resources\BlogTopics'); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/spec/Resources/BlogAuthorsSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith('demo', $client); 13 | } 14 | 15 | public function it_is_initializable() 16 | { 17 | $this->shouldHaveType('SevenShores\Hubspot\Resources\BlogAuthors'); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/spec/Resources/ContactListsSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith('demo', $client); 13 | } 14 | 15 | public function it_is_initializable() 16 | { 17 | $this->shouldHaveType('SevenShores\Hubspot\Resources\ContactLists'); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/spec/Resources/EmailEventsSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith('demo', $client); 13 | } 14 | 15 | public function it_is_initializable() 16 | { 17 | $this->shouldHaveType('SevenShores\Hubspot\Resources\EmailEvents'); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/spec/Resources/SocialMediaSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith('demo', $client); 13 | } 14 | 15 | public function it_is_initializable() 16 | { 17 | $this->shouldHaveType('SevenShores\Hubspot\Resources\SocialMedia'); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/Integration/Resources/CompanyPropertyGroupsTest.php: -------------------------------------------------------------------------------- 1 | beConstructedWith('demo', $client); 13 | } 14 | 15 | public function it_is_initializable() 16 | { 17 | $this->shouldHaveType('SevenShores\Hubspot\Resources\ContactProperties'); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/spec/Resources/EmailSubscriptionSpec.php: -------------------------------------------------------------------------------- 1 | beConstructedWith('demo', $client); 13 | } 14 | 15 | public function it_is_initializable() 16 | { 17 | $this->shouldHaveType('SevenShores\Hubspot\Resources\EmailSubscription'); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Utils.php: -------------------------------------------------------------------------------- 1 | 'name', 'value' => $name], 11 | ['name' => 'description', 'value' => 'A description of this product.'], 12 | ['name' => 'price', 'value' => 27.50], 13 | ['name' => 'recurringbillingfrequency', 'value' => 'quarterly'], 14 | ]; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Utils/Webhooks.php: -------------------------------------------------------------------------------- 1 | beConstructedWith('demo', $client); 16 | } 17 | 18 | public function it_is_initializable() 19 | { 20 | $this->shouldHaveType('SevenShores\Hubspot\Resources\Companies'); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /tests/Integration/Resources/DealPropertyGroupsTest.php: -------------------------------------------------------------------------------- 1 | beConstructedWith('demo', $client); 16 | } 17 | 18 | public function it_is_initializable() 19 | { 20 | $this->shouldHaveType('SevenShores\Hubspot\Resources\DealProperties'); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /tests/Integration/Resources/ContactPropertyGroupsTest.php: -------------------------------------------------------------------------------- 1 | beConstructedWith('demo', $client); 16 | } 17 | 18 | public function it_is_initializable() 19 | { 20 | $this->shouldHaveType('SevenShores\Hubspot\Resources\CompanyProperties'); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /tests/Integration/Resources/DealPropertiesTest.php: -------------------------------------------------------------------------------- 1 | resource = Factory::create(getenv('HUBSPOT_TEST_API_KEY'))->objectProperties('products'); 22 | sleep(1); 23 | $this->entity = $this->createEntity(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /tests/Integration/Resources/ObjectPropertiesTest.php: -------------------------------------------------------------------------------- 1 | resource = Factory::create(getenv('HUBSPOT_TEST_API_KEY'))->objectProperties('products'); 22 | sleep(1); 23 | $this->entity = $this->createEntity(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /tests/Helpers/SendsRequests.php: -------------------------------------------------------------------------------- 1 | 'SevenShores_Hubspot_PHP/1.0 (https://github.com/ryanwinchester/hubspot-php)', 13 | ]; 14 | 15 | protected function buildQuery($query = []) 16 | { 17 | return build_query_string($query); 18 | } 19 | 20 | protected function buildUrl($endpoint, $query_string = null) 21 | { 22 | return $this->base_url.$endpoint.$this->auth.$query_string; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Resources/Resource.php: -------------------------------------------------------------------------------- 1 | client = $client; 20 | } 21 | 22 | /** 23 | * Convert a time, DateTime, or string to a millisecond timestamp. 24 | * 25 | * @param null|\DateTime|int $time 26 | * 27 | * @return null|int 28 | */ 29 | protected function timestamp($time) 30 | { 31 | return ms_timestamp($time); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /tests/Integration/Abstraction/EntityTestCase.php: -------------------------------------------------------------------------------- 1 | entity = $this->createEntity(); 17 | sleep(1); 18 | } 19 | 20 | public function tearDown(): void 21 | { 22 | parent::tearDown(); 23 | if (!empty($this->entity)) { 24 | $this->deleteEntity(); 25 | } 26 | } 27 | 28 | abstract protected function createEntity(); 29 | 30 | abstract protected function deleteEntity(); 31 | } 32 | -------------------------------------------------------------------------------- /tests/unit/Utils/OAuth2Test.php: -------------------------------------------------------------------------------- 1 | assertEquals( 23 | 'https://app.hubspot.com/oauth/authorize?client_id=clientid&redirect_uri=http%3A%2F%2Flocalhost&scope=contacts%20timeline&optional_scope=scope1%20scope2', 24 | $authUrl 25 | ); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ./src/ 6 | 7 | 8 | 9 | 10 | ./tests 11 | 12 | 13 | ./tests/unit 14 | 15 | 16 | ./tests/Integration 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /tests/spec/Resources/ContactsSpec.php: -------------------------------------------------------------------------------- 1 | 'Fungku_HubSpot_PHP/0.9 (https://github.com/fungku/hubspot-php)', 18 | ]; 19 | 20 | public function let(Client $client) 21 | { 22 | $this->beConstructedWith('demo', $client); 23 | } 24 | 25 | public function it_is_initializable() 26 | { 27 | $this->shouldHaveType('SevenShores\Hubspot\Resources\Contacts'); 28 | } 29 | 30 | private function getUrl($endpoint) 31 | { 32 | return $this->baseUrl.$endpoint.'?hapikey='.$this->apiKey; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Resources/Integration.php: -------------------------------------------------------------------------------- 1 | client->request('get', $endpoint); 19 | } 20 | 21 | /** 22 | * Check daily API usage. 23 | * 24 | * @return \SevenShores\Hubspot\Http\Response 25 | * 26 | * @see https://developers.hubspot.com/docs/methods/check-daily-api-usage 27 | */ 28 | public function getDailyUsage() 29 | { 30 | $endpoint = 'https://api.hubapi.com/integrations/v1/limit/daily'; 31 | 32 | return $this->client->request('get', $endpoint); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hubspot/hubspot-php", 3 | "version": "4.0.1", 4 | "description": "HubSpot PHP API client", 5 | "keywords": [ "hubspot", "api" ], 6 | "license": "Apache-2.0", 7 | "authors": [ 8 | { 9 | "name": "Ryan Winchester", 10 | "email": "fungku@gmail.com", 11 | "homepage": "http://ryanwinchester.ca" 12 | } 13 | ], 14 | "require": { 15 | "php": ">=7.3", 16 | "ext-json": "*", 17 | "guzzlehttp/guzzle": "^7.3" 18 | }, 19 | "require-dev": { 20 | "friendsofphp/php-cs-fixer": "^3.4", 21 | "phpunit/phpunit": "^9.5", 22 | "phpspec/phpspec": "^7.1" 23 | }, 24 | "autoload": { 25 | "psr-4": { 26 | "SevenShores\\Hubspot\\": "src/" 27 | }, 28 | "files": [ "src/helpers.php" ] 29 | }, 30 | "autoload-dev": { 31 | "psr-4": { 32 | "SevenShores\\Hubspot\\Tests\\": "tests/" 33 | } 34 | }, 35 | "minimum-stability": "stable" 36 | } 37 | -------------------------------------------------------------------------------- /src/Exceptions/HubspotException.php: -------------------------------------------------------------------------------- 1 | response; 20 | } 21 | 22 | public static function create(RequestException $guzzleException): self 23 | { 24 | $e = new static( 25 | static::sanitizeResponseMessage($guzzleException->getMessage()), 26 | $guzzleException->getCode() 27 | ); 28 | 29 | $e->response = $guzzleException->getResponse(); 30 | 31 | return $e; 32 | } 33 | 34 | protected static function sanitizeResponseMessage(string $message): string 35 | { 36 | return preg_replace('/(hapikey|access_token)=[a-z0-9-]+/i', '$1=***', $message); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /tests/Integration/Abstraction/DefaultTestCase.php: -------------------------------------------------------------------------------- 1 | resource)) { 34 | $this->resource = new $this->resourceClass($this->getClient()); 35 | } 36 | sleep(1); 37 | } 38 | 39 | protected function getClient(): Client 40 | { 41 | return new Client(['key' => getenv($this->key)]); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /tests/Integration/Resources/IntegrationTest.php: -------------------------------------------------------------------------------- 1 | integration = new Integration(new Client(['key' => getenv('HUBSPOT_TEST_API_KEY')])); 27 | sleep(1); 28 | } 29 | 30 | /** @test */ 31 | public function getDailyUsage() 32 | { 33 | $response = $this->integration->getDailyUsage(); 34 | 35 | $this->assertEquals(200, $response->getStatusCode()); 36 | $data = $response->toArray(); 37 | $this->assertNotEmpty($data); 38 | $data = reset($data); 39 | $this->assertNotEmpty($data['usageLimit']); 40 | $this->assertNotEmpty($data['currentUsage']); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Utils/OAuth2.php: -------------------------------------------------------------------------------- 1 | $clientId, 21 | 'redirect_uri' => $redirectURI, 22 | 'scope' => implode(' ', $scopesArray), 23 | 'optional_scope' => implode(' ', $optionalScopesArray), 24 | ], null, '&', PHP_QUERY_RFC3986); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /tests/unit/Utils/WebhooksTest.php: -------------------------------------------------------------------------------- 1 | secret.$this->requestBody), 21 | $this->secret, 22 | $this->requestBody 23 | ); 24 | 25 | $this->assertEquals( 26 | true, 27 | $result 28 | ); 29 | } 30 | 31 | /** @test */ 32 | public function validationHubspotSignatureInvalidData() 33 | { 34 | $result = Utils\Webhooks::isHubspotSignatureValid( 35 | hash('sha256', $this->secret.$this->requestBody.'1'), 36 | $this->secret, 37 | $this->requestBody 38 | ); 39 | 40 | $this->assertEquals( 41 | false, 42 | $result 43 | ); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /tests/Integration/Abstraction/TimelineWithProprtyTestCase.php: -------------------------------------------------------------------------------- 1 | property = $this->createProperty(); 16 | } 17 | 18 | public function tearDown(): void 19 | { 20 | if (!empty($this->property)) { 21 | $this->deleteProperty(); 22 | } 23 | 24 | parent::tearDown(); 25 | } 26 | 27 | public function deleteProperty() 28 | { 29 | return $this->resource->deleteEventTypeProperty( 30 | $this->appId, 31 | $this->entity->id, 32 | $this->property->id 33 | ); 34 | } 35 | 36 | protected function createProperty() 37 | { 38 | return $this->resource->createEventTypeProperty( 39 | $this->appId, 40 | $this->entity->id, 41 | 'test_property', 42 | 'Property', 43 | 'String' 44 | ); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /tests/Integration/Abstraction/HubDBRowTestCase.php: -------------------------------------------------------------------------------- 1 | portalId = getenv('HUBSPOT_TEST_PORTAL_ID'); 31 | 32 | parent::setUp(); 33 | } 34 | 35 | protected function createEntity() 36 | { 37 | return $this->resource->createTable('Test Table'.uniqid(), [ 38 | [ 39 | 'name' => 'Name', 40 | 'type' => 'TEXT', 41 | ], 42 | [ 43 | 'name' => 'Count', 44 | 'type' => 'NUMBER', 45 | ], 46 | ]); 47 | } 48 | 49 | protected function deleteEntity() 50 | { 51 | return $this->resource->deleteTable($this->entity->id); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /tests/Integration/Abstraction/BlogPostTestCase.php: -------------------------------------------------------------------------------- 1 | getenv($this->key)])); 20 | $this->blogId = $blogs->all(['limit' => 1])->objects[0]->id; 21 | 22 | $blogAuthor = new BlogAuthors(new Client(['key' => getenv($this->key)])); 23 | $this->authorId = $blogAuthor->all(['limit' => 1])->objects[0]->id; 24 | 25 | parent::setUp(); 26 | } 27 | 28 | protected function createPost(BlogPosts $resource) 29 | { 30 | $date = new DateTime(); 31 | 32 | return $resource->create([ 33 | 'name' => 'My Super Awesome Post '.uniqid(), 34 | 'content_group_id' => $this->blogId, 35 | 'publish_date' => $date->getTimestamp(), 36 | 'blog_author_id' => $this->authorId, 37 | 'meta_description' => 'My Super Awesome Post ...', 38 | 'slug' => '/blog/'.uniqid().'/my-first-api-blog-post', 39 | ]); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /tests/Integration/Abstraction/TimelineTestCase.php: -------------------------------------------------------------------------------- 1 | appId = getenv('HUBSPOT_TEST_APP_ID'); 37 | 38 | parent::setUp(); 39 | } 40 | 41 | public function deleteEntity() 42 | { 43 | return $this->resource->deleteEventType( 44 | $this->appId, 45 | $this->entity->id 46 | ); 47 | } 48 | 49 | protected function createEntity() 50 | { 51 | return $this->resource->createEventType( 52 | $this->appId, 53 | 'Test Event Name', 54 | 'Test Event header template', 55 | 'Test Event detail template', 56 | 'CONTACT' 57 | ); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/Resources/TransactionalEmail.php: -------------------------------------------------------------------------------- 1 | client->request('get', $endpoint); 20 | } 21 | 22 | /** 23 | * Send an email designed and maintained in the HubSpot marketing Email Tool. 24 | * 25 | * @see https://developers.hubspot.com/docs/methods/email/transactional_email/single-send-overview 26 | * 27 | * @param int $id 28 | * @param array $message 29 | * @param array $contactProperties 30 | * @param array $customProperties 31 | * 32 | * @return \SevenShores\Hubspot\Http\Response 33 | */ 34 | public function send($id, $message = [], $contactProperties = [], $customProperties = []) 35 | { 36 | $endpoint = 'https://api.hubapi.com/email/public/v1/singleEmail/send'; 37 | 38 | $options['json'] = [ 39 | 'emailId' => $id, 40 | 'message' => $message, 41 | 'contactProperties' => $contactProperties, 42 | 'customProperties' => $customProperties, 43 | ]; 44 | 45 | return $this->client->request('post', $endpoint, $options); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /tests/Integration/Resources/EventsTest.php: -------------------------------------------------------------------------------- 1 | events = new Events(new Client(['key' => getenv('HUBSPOT_TEST_API_KEY')])); 20 | sleep(1); 21 | } 22 | 23 | /** @test */ 24 | public function trigger() 25 | { 26 | $response = $this->events->trigger(56043, 000000001625); 27 | 28 | $this->assertEquals(200, $response->getStatusCode()); 29 | } 30 | 31 | /** @test */ 32 | public function triggerWithEmail() 33 | { 34 | $response = $this->events->trigger(56043, 000000001625, 'test@hubspot.com'); 35 | 36 | $this->assertEquals(200, $response->getStatusCode()); 37 | } 38 | 39 | /** @test */ 40 | public function triggerWithRevenue() 41 | { 42 | $response = $this->events->trigger(56043, 000000001625, 'test@hubspot.com', 50); 43 | 44 | $this->assertEquals(200, $response->getStatusCode()); 45 | } 46 | 47 | /** @test */ 48 | public function triggerWithProperties() 49 | { 50 | $response = $this->events->trigger(56043, 000000001625, 'test@hubspot.com', 50, [ 51 | 'firstname' => 'Joe', 52 | ]); 53 | 54 | $this->assertEquals(200, $response->getStatusCode()); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /tests/Integration/Resources/BlogsTest.php: -------------------------------------------------------------------------------- 1 | resource->all(); 28 | 29 | $this->assertEquals(200, $response->getStatusCode()); 30 | } 31 | 32 | /** @test */ 33 | public function allWithParams() 34 | { 35 | $response = $this->resource->all(['limit' => 1]); 36 | 37 | $this->assertEquals(200, $response->getStatusCode()); 38 | $this->assertNotNull($response->objects[0]->created); 39 | } 40 | 41 | /** @test */ 42 | public function allWithParamsAndArrayAccess() 43 | { 44 | $response = $this->resource->all(['limit' => 1]); 45 | 46 | $this->assertEquals(200, $response->getStatusCode()); 47 | $this->assertNotNull($response['objects'][0]['created']); 48 | } 49 | 50 | /** @test */ 51 | public function getById() 52 | { 53 | $blogs = $this->resource->all(['limit' => 1]); 54 | 55 | $response = $this->resource->getById($blogs->objects[0]->id); 56 | 57 | $this->assertEquals(200, $response->getStatusCode()); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /tests/Integration/Resources/OwnersTest.php: -------------------------------------------------------------------------------- 1 | owners = new Owners(new Client(['key' => getenv('HUBSPOT_TEST_API_KEY')])); 27 | sleep(1); 28 | } 29 | 30 | /** 31 | * @test 32 | */ 33 | public function get() 34 | { 35 | $owner = $this->owners->all(['email' => getenv('HUBSPOT_TEST_EMAIL')])->getData()[0]; 36 | 37 | $response = $this->owners->getById($owner->ownerId); 38 | $this->assertSame(200, $response->getStatusCode()); 39 | $this->assertSame($owner->email, $response->email); 40 | } 41 | 42 | /** 43 | * @test 44 | */ 45 | public function findByEmail() 46 | { 47 | $response = $this->owners->all(['email' => getenv('HUBSPOT_TEST_EMAIL')]); 48 | $this->assertSame(200, $response->getStatusCode()); 49 | $this->assertSame(getenv('HUBSPOT_TEST_EMAIL'), $response->getData()[0]->email); 50 | } 51 | 52 | /** 53 | * @test 54 | */ 55 | public function all() 56 | { 57 | $response = $this->owners->all(); 58 | $this->assertSame(200, $response->getStatusCode()); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /tests/Integration/Resources/EmailSubscriptionTest.php: -------------------------------------------------------------------------------- 1 | resource = new EmailSubscription(new Client(['key' => getenv('HUBSPOT_TEST_API_KEY')])); 24 | sleep(1); 25 | } 26 | 27 | /** @test */ 28 | public function subscriptions() 29 | { 30 | $response = $this->resource->subscriptions(); 31 | 32 | $this->assertEquals(200, $response->getStatusCode()); 33 | } 34 | 35 | /** @test */ 36 | public function subscriptionsTimeline() 37 | { 38 | $response = $this->resource->subscriptionsTimeline(['limit' => 2]); 39 | 40 | $this->assertEquals(200, $response->getStatusCode()); 41 | } 42 | 43 | /** @test */ 44 | public function subscriptionStatus() 45 | { 46 | $response = $this->resource->subscriptionStatus('test@hubspot.com'); 47 | 48 | $this->assertEquals(200, $response->getStatusCode()); 49 | } 50 | 51 | /** @test */ 52 | public function updateSubscription() 53 | { 54 | $response = $this->resource->updateSubscription('test@hubspot.com', ['unsubscribeFromAll' => true]); 55 | 56 | $this->assertEquals(200, $response->getStatusCode()); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/Resources/Events.php: -------------------------------------------------------------------------------- 1 | $contactRevenue], 38 | $contactProperties 39 | ); 40 | 41 | $query_string = build_query_string($parameters); 42 | 43 | return $this->client->request('get', $endpoint, [], $query_string, false); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /tests/Integration/Abstraction/ContactListsTestCase.php: -------------------------------------------------------------------------------- 1 | resource->create( 37 | [ 38 | 'name' => 'Test '.uniqid(), 39 | 'dynamic' => $this->dynamic, 40 | 'portalId' => getenv('HUBSPOT_TEST_PORTAL_ID'), 41 | 'filters' => [ 42 | [ 43 | [ 44 | 'operator' => 'EQ', 45 | 'value' => '@hubspot', 46 | 'property' => 'twitterhandle', 47 | 'type' => 'string', 48 | ], 49 | ], 50 | ], 51 | ] 52 | ); 53 | } 54 | 55 | protected function deleteEntity() 56 | { 57 | return $this->resource->delete($this->entity->listId); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /tests/Integration/Resources/TimelineEventTypeProprtyTest.php: -------------------------------------------------------------------------------- 1 | resource->getEventTypeProperties($this->appId, $this->entity->id); 19 | 20 | $this->assertEquals(200, $response->getStatusCode()); 21 | $this->assertGreaterThanOrEqual(1, count($response->toArray())); 22 | } 23 | 24 | /** 25 | * @test 26 | */ 27 | public function createEventTypeProperty() 28 | { 29 | $this->assertEquals(200, $this->property->getStatusCode()); 30 | $this->assertEquals('test_property', $this->property->name); 31 | } 32 | 33 | /** 34 | * @test 35 | */ 36 | public function updateEventTypeProperty() 37 | { 38 | $response = $this->resource->updateEventTypeProperty( 39 | $this->appId, 40 | $this->entity->id, 41 | $this->property->id, 42 | $this->property->name, 43 | 'Updated Property', 44 | 'String' 45 | ); 46 | 47 | $this->assertEquals(200, $response->getStatusCode()); 48 | $this->assertEquals('Updated Property', $response->label); 49 | } 50 | 51 | /** 52 | * @test 53 | */ 54 | public function deleteEventTypeProperty() 55 | { 56 | $response = $this->deleteProperty(); 57 | 58 | $this->assertEquals(204, $response->getStatusCode()); 59 | 60 | $this->property = null; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/Resources/Keywords.php: -------------------------------------------------------------------------------- 1 | $search]); 19 | 20 | return $this->client->request('get', $endpoint, [], $queryString); 21 | } 22 | 23 | /** 24 | * Get a keyword. 25 | * 26 | * @param string $keyword_guid 27 | * 28 | * @return \SevenShores\Hubspot\Http\Response 29 | */ 30 | public function getById($keyword_guid) 31 | { 32 | $endpoint = "https://api.hubapi.com/keywords/v1/keywords/{$keyword_guid}"; 33 | 34 | return $this->client->request('get', $endpoint); 35 | } 36 | 37 | /** 38 | * Create a new keyword. 39 | * 40 | * @param array $keyword 41 | * 42 | * @return \SevenShores\Hubspot\Http\Response 43 | */ 44 | public function create($keyword) 45 | { 46 | $endpoint = 'https://api.hubapi.com/keywords/v1/keywords'; 47 | 48 | $options['json'] = $keyword; 49 | 50 | return $this->client->request('put', $endpoint, $options); 51 | } 52 | 53 | /** 54 | * Delete a keyword. 55 | * 56 | * @param string $keyword_guid 57 | * 58 | * @return \SevenShores\Hubspot\Http\Response 59 | */ 60 | public function delete($keyword_guid) 61 | { 62 | $endpoint = "https://api.hubapi.com/keywords/v1/keywords/{$keyword_guid}"; 63 | 64 | return $this->client->request('delete', $endpoint); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/Resources/Owners.php: -------------------------------------------------------------------------------- 1 | client->request('post', $endpoint, $options); 23 | } 24 | 25 | /** 26 | * @param int $id 27 | * 28 | * @return \SevenShores\Hubspot\Http\Response 29 | * 30 | * @deprecated 31 | */ 32 | public function update($id, array $properties) 33 | { 34 | $endpoint = "https://api.hubapi.com/owners/v2/owners/{$id}"; 35 | $options['json'] = $properties; 36 | 37 | return $this->client->request('put', $endpoint, $options); 38 | } 39 | 40 | /** 41 | * @param int $id 42 | * 43 | * @return \SevenShores\Hubspot\Http\Response 44 | * 45 | * @see https://developers.hubspot.com/docs/methods/owners/get_an_owner 46 | */ 47 | public function getById($id) 48 | { 49 | $endpoint = 'https://api.hubapi.com/owners/v2/owners/'.$id; 50 | 51 | return $this->client->request('get', $endpoint); 52 | } 53 | 54 | /** 55 | * @return \SevenShores\Hubspot\Http\Response 56 | * 57 | * @see https://developers.hubspot.com/docs/methods/owners/get_owners 58 | */ 59 | public function all(array $params = []) 60 | { 61 | $endpoint = 'https://api.hubapi.com/owners/v2/owners'; 62 | 63 | $queryString = build_query_string($params); 64 | 65 | return $this->client->request('get', $endpoint, [], $queryString); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /tests/Integration/Resources/AnalyticsTest.php: -------------------------------------------------------------------------------- 1 | resource->getByCategory('totals', 'total', '20180101', '20180301'); 28 | 29 | $this->assertEquals(200, $response->getStatusCode()); 30 | } 31 | 32 | /** @test */ 33 | public function getByType() 34 | { 35 | $response = $this->resource->getByType('forms', 'total', '20180101', '20180301'); 36 | 37 | $this->assertEquals(200, $response->getStatusCode()); 38 | } 39 | 40 | /** @test */ 41 | public function getHosted() 42 | { 43 | $response = $this->resource->getHosted('standard-pages', 'total', '20180101', '20180301'); 44 | 45 | $this->assertEquals(200, $response->getStatusCode()); 46 | } 47 | 48 | /** @test */ 49 | public function checkForExistence() 50 | { 51 | $response = $this->resource->checkForExistence('event-completions'); 52 | 53 | $this->assertEquals(200, $response->getStatusCode()); 54 | } 55 | 56 | /** @test */ 57 | public function getEvents() 58 | { 59 | $response = $this->resource->getEvents(); 60 | 61 | $this->assertEquals(200, $response->getStatusCode()); 62 | } 63 | 64 | /** @test */ 65 | public function getViews() 66 | { 67 | $response = $this->resource->getViews(); 68 | 69 | $this->assertEquals(200, $response->getStatusCode()); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /tests/Integration/Resources/TimelineEventTypeTest.php: -------------------------------------------------------------------------------- 1 | resource->getEventTypes($this->appId); 19 | 20 | $this->assertEquals(200, $response->getStatusCode()); 21 | $this->assertGreaterThanOrEqual(1, count($response->toArray())); 22 | } 23 | 24 | /** 25 | * @test 26 | */ 27 | public function getEventTypeById() 28 | { 29 | $response = $this->resource->getEventTypeById($this->appId, $this->entity->id); 30 | 31 | $this->assertEquals(200, $response->getStatusCode()); 32 | $this->assertContains($this->entity->id, $response->toArray()); 33 | } 34 | 35 | /** 36 | * @test 37 | */ 38 | public function createEventType() 39 | { 40 | $this->assertEquals(200, $this->entity->getStatusCode()); 41 | $this->assertEquals('Test Event Name', $this->entity->name); 42 | } 43 | 44 | /** 45 | * @test 46 | */ 47 | public function updateEventType() 48 | { 49 | $response = $this->resource->updateEventType( 50 | $this->appId, 51 | $this->entity->id, 52 | 'Updated Test Event Name', 53 | 'Updated Test Event header template', 54 | 'Updated Test Event detail template' 55 | ); 56 | 57 | $this->assertEquals(200, $response->getStatusCode()); 58 | $this->assertEquals('Updated Test Event Name', $response->name); 59 | } 60 | 61 | /** 62 | * @test 63 | */ 64 | public function deleteEventType() 65 | { 66 | $response = $this->deleteEntity(); 67 | 68 | $this->assertEquals(204, $response->getStatusCode()); 69 | 70 | $this->entity = null; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /tests/Integration/Resources/EmailEventsTest.php: -------------------------------------------------------------------------------- 1 | resource = new EmailEvents(new Client(['key' => getenv('HUBSPOT_TEST_API_KEY')])); 20 | sleep(1); 21 | } 22 | 23 | /** @test */ 24 | public function all() 25 | { 26 | $response = $this->resource->all(); 27 | 28 | $this->assertEquals(200, $response->getStatusCode()); 29 | } 30 | 31 | /** @test */ 32 | public function getById() 33 | { 34 | $list = $this->resource->all(['limit' => 2]); 35 | 36 | if (count($list->events) > 0) { 37 | $response = $this->resource->getById( 38 | $list->events[0]->id, 39 | $list->events[0]->created 40 | ); 41 | 42 | $this->assertEquals(200, $response->getStatusCode()); 43 | } 44 | } 45 | 46 | /** @test */ 47 | public function getCampaignIds() 48 | { 49 | $response = $this->resource->getCampaignIds(['limit' => 2]); 50 | 51 | $this->assertEquals(200, $response->getStatusCode()); 52 | } 53 | 54 | /** @test */ 55 | public function getCampaignIdsWithRecentActivity() 56 | { 57 | $response = $this->resource->getCampaignIdsWithRecentActivity(['limit' => 2]); 58 | 59 | $this->assertEquals(200, $response->getStatusCode()); 60 | } 61 | 62 | /** @test */ 63 | public function getCampaignById() 64 | { 65 | $list = $this->resource->getCampaignIds(['limit' => 2]); 66 | 67 | if (count($list->campaigns) > 0) { 68 | $response = $this->resource->getCampaignById( 69 | $list->campaigns[0]->id, 70 | $list->campaigns[0]->appId 71 | ); 72 | 73 | $this->assertEquals(200, $response->getStatusCode()); 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /tests/Integration/Resources/PagesTest.php: -------------------------------------------------------------------------------- 1 | assertEquals(201, $this->entity->getStatusCode()); 22 | } 23 | 24 | /** @test */ 25 | public function update() 26 | { 27 | $response = $this->resource->update( 28 | $this->entity->id, 29 | ['name' => 'Updated '.$this->entity->name] 30 | ); 31 | 32 | $this->assertEquals(200, $response->getStatusCode()); 33 | } 34 | 35 | /** @test */ 36 | public function getById() 37 | { 38 | $response = $this->resource->getById($this->entity->id); 39 | 40 | $this->assertEquals(200, $response->getStatusCode()); 41 | } 42 | 43 | /** @test */ 44 | public function delete() 45 | { 46 | $response = $this->deleteEntity(); 47 | 48 | $this->assertEquals(204, $response->getStatusCode()); 49 | 50 | $this->entity = null; 51 | } 52 | 53 | /** @test */ 54 | public function all() 55 | { 56 | $response = $this->resource->all(); 57 | 58 | $this->assertEquals(200, $response->getStatusCode()); 59 | } 60 | 61 | /** @test */ 62 | public function clonePage() 63 | { 64 | $response = $this->resource->clonePage($this->entity->id, 'New page name'); 65 | 66 | $this->assertEquals(201, $response->getStatusCode()); 67 | 68 | $this->resource->delete($response->id); 69 | } 70 | 71 | protected function createEntity() 72 | { 73 | return $this->resource->create([ 74 | 'name' => 'My Super Awesome Post(AutoTest)', 75 | ]); 76 | } 77 | 78 | protected function deleteEntity() 79 | { 80 | return $this->resource->delete($this->entity->id); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /tests/Integration/Resources/KeywordsTest.php: -------------------------------------------------------------------------------- 1 | markTestSkipped(); // TODO: fix test 20 | $this->keywords = new Keywords(new Client(['key' => 'demooooo-oooo-oooo-oooo-oooooooooooo', 'oauth' => true])); 21 | sleep(1); 22 | } 23 | 24 | /** @test */ 25 | public function all() 26 | { 27 | $response = $this->keywords->all(); 28 | 29 | sleep(1); 30 | 31 | $this->assertEquals(200, $response->getStatusCode()); 32 | $this->assertGreaterThanOrEqual(1, count($response->getData())); 33 | } 34 | 35 | /** @test */ 36 | public function allWithSearch() 37 | { 38 | $response = $this->keywords->all('marketing'); 39 | 40 | sleep(1); 41 | 42 | $this->assertEquals(200, $response->getStatusCode()); 43 | } 44 | 45 | /** @test */ 46 | public function getById() 47 | { 48 | $keyword = $this->createKeyword(); 49 | 50 | $response = $this->keywords->getById($keyword->keywords[0]->keyword_guid); 51 | 52 | sleep(1); 53 | 54 | $this->assertEquals(200, $response->getStatusCode()); 55 | } 56 | 57 | /** @test */ 58 | public function delete() 59 | { 60 | $keyword = $this->createKeyword(); 61 | 62 | $response = $this->keywords->delete($keyword->keywords[0]->keyword_guid); 63 | 64 | sleep(1); 65 | 66 | $this->assertEquals(204, $response->getStatusCode()); 67 | } 68 | 69 | // Lots of tests need an existing object to modify. 70 | private function createKeyword() 71 | { 72 | $response = $this->keywords->create([ 73 | 'keyword' => 'k '.uniqid(), 74 | ]); 75 | 76 | $this->assertEquals(201, $response->getStatusCode()); 77 | 78 | sleep(1); 79 | 80 | return $response; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/Resources/Blogs.php: -------------------------------------------------------------------------------- 1 | client->request( 21 | 'get', 22 | $endpoint, 23 | [], 24 | build_query_string($params) 25 | ); 26 | } 27 | 28 | /** 29 | * Get information about a specific blog. 30 | * 31 | * @param int $id 32 | * 33 | * @see https://developers.hubspot.com/docs/methods/blogv2/get_blogs_blog_id 34 | * 35 | * @return \SevenShores\Hubspot\Http\Response 36 | */ 37 | public function getById($id) 38 | { 39 | $endpoint = "https://api.hubapi.com/content/api/v2/blogs/{$id}"; 40 | 41 | return $this->client->request('get', $endpoint); 42 | } 43 | 44 | /** 45 | * Get previous versions of the blog. 46 | * 47 | * @param int $id blog id 48 | * 49 | * @see https://developers.hubspot.com/docs/methods/blogv2/get_blogs_blog_id_versions 50 | * 51 | * @return \SevenShores\Hubspot\Http\Response 52 | */ 53 | public function versions($id) 54 | { 55 | $endpoint = "https://api.hubapi.com/content/api/v2/blogs/{$id}/versions"; 56 | 57 | return $this->client->request('get', $endpoint); 58 | } 59 | 60 | /** 61 | * Get a previous version of the blog. 62 | * 63 | * @param int $id blog id 64 | * @param int $version_id version id 65 | * 66 | * @see https://developers.hubspot.com/docs/methods/blogv2/get_blogs_blog_id_versions_version_id 67 | * 68 | * @return \SevenShores\Hubspot\Http\Response 69 | */ 70 | public function getVersion($id, $version_id) 71 | { 72 | $endpoint = "https://api.hubapi.com/content/api/v2/blogs/{$id}/versions/{$version_id}"; 73 | 74 | return $this->client->request('get', $endpoint); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /tests/Integration/Resources/ContactDinamicListsTest.php: -------------------------------------------------------------------------------- 1 | contactsResource = new Contacts($this->getClient()); 29 | } 30 | 31 | /** @test */ 32 | public function getAllDynamic() 33 | { 34 | $response = $this->resource->getAllStatic(); 35 | 36 | $this->assertEquals(200, $response->getStatusCode()); 37 | } 38 | 39 | /** @test */ 40 | public function addContact() 41 | { 42 | $contact = $this->createContact(); 43 | 44 | $response = $this->resource->addContact($this->entity->listId, [$contact->vid]); 45 | 46 | $this->assertEquals(200, $response->getStatusCode()); 47 | 48 | $this->resource->removeContact($this->entity->listId, [$contact->vid]); 49 | 50 | $this->contactsResource->delete($contact->vid); 51 | } 52 | 53 | /** @test */ 54 | public function removeContact() 55 | { 56 | $contact = $this->createContact(); 57 | 58 | $this->resource->addContact($this->entity->listId, [$contact->vid]); 59 | 60 | $response = $this->resource->removeContact($this->entity->listId, [$contact->vid]); 61 | 62 | $this->assertEquals(200, $response->getStatusCode()); 63 | 64 | $this->contactsResource->delete($contact->vid); 65 | } 66 | 67 | /** 68 | * Creates a new contact. 69 | * 70 | * @return \SevenShores\Hubspot\Http\Response 71 | */ 72 | protected function createContact() 73 | { 74 | $contactResponse = $this->contactsResource->create([ 75 | ['property' => 'email', 'value' => 'ContactListsTest'.uniqid().'@hubspot.com'], 76 | ['property' => 'firstname', 'value' => 'joe'], 77 | ['property' => 'lastname', 'value' => 'user'], 78 | ]); 79 | 80 | sleep(1); 81 | 82 | return $contactResponse; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/Resources/SocialMedia.php: -------------------------------------------------------------------------------- 1 | client->request('get', $endpoint); 17 | } 18 | 19 | /** 20 | * Get a broadcast channel. 21 | * 22 | * @param string $channel_guid 23 | * 24 | * @return \SevenShores\Hubspot\Http\Response 25 | */ 26 | public function getChannelById($channel_guid) 27 | { 28 | $endpoint = "https://api.hubapi.com/broadcast/v1/channels/{$channel_guid}"; 29 | 30 | return $this->client->request('get', $endpoint); 31 | } 32 | 33 | /** 34 | * Get all broadcast messages. 35 | * 36 | * @param array $params 37 | * 38 | * @return \SevenShores\Hubspot\Http\Response 39 | */ 40 | public function broadcasts($params = []) 41 | { 42 | $endpoint = 'https://api.hubapi.com/broadcast/v1/broadcasts'; 43 | 44 | $queryString = build_query_string($params); 45 | 46 | return $this->client->request('get', $endpoint, [], $queryString); 47 | } 48 | 49 | /** 50 | * Get a broadcast. 51 | * 52 | * @param string $broadcast_guid 53 | * 54 | * @return \SevenShores\Hubspot\Http\Response 55 | */ 56 | public function getBroadcastById($broadcast_guid) 57 | { 58 | $endpoint = "https://api.hubapi.com/broadcast/v1/broadcasts/{$broadcast_guid}"; 59 | 60 | return $this->client->request('get', $endpoint); 61 | } 62 | 63 | /** 64 | * Create a new broadcast message. 65 | * 66 | * @param array $broadcast 67 | * 68 | * @return \SevenShores\Hubspot\Http\Response 69 | */ 70 | public function createBroadcast($broadcast) 71 | { 72 | $endpoint = 'https://api.hubapi.com/broadcast/v1/broadcasts'; 73 | 74 | $options['json'] = $broadcast; 75 | 76 | return $this->client->request('post', $endpoint, $options); 77 | } 78 | 79 | /** 80 | * Cancel a broadcast message. 81 | * 82 | * @param string $broadcast_guid 83 | * 84 | * @return \SevenShores\Hubspot\Http\Response 85 | */ 86 | public function cancelBroadcast($broadcast_guid) 87 | { 88 | $endpoint = "https://api.hubapi.com/broadcast/v1/broadcasts/{$broadcast_guid}"; 89 | 90 | return $this->client->request('delete', $endpoint); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/Resources/BlogComments.php: -------------------------------------------------------------------------------- 1 | client->request( 21 | 'get', 22 | $endpoint, 23 | [], 24 | build_query_string($params) 25 | ); 26 | } 27 | 28 | /** 29 | * Get information about a specific comment. 30 | * 31 | * @param mixed $id 32 | * 33 | * @see https://developers.hubspot.com/docs/methods/comments/get_comments_comment_id 34 | * 35 | * @return \SevenShores\Hubspot\Http\Response 36 | */ 37 | public function getById($id) 38 | { 39 | $endpoint = "https://api.hubapi.com/comments/v3/comments/{$id}"; 40 | 41 | return $this->client->request('get', $endpoint); 42 | } 43 | 44 | /** 45 | * Create a new comment. 46 | * 47 | * @see https://developers.hubspot.com/docs/methods/comments/post_comments 48 | * 49 | * @return \SevenShores\Hubspot\Http\Response 50 | */ 51 | public function create(array $properties) 52 | { 53 | $endpoint = 'https://api.hubapi.com/comments/v3/comments'; 54 | 55 | return $this->client->request('post', $endpoint, ['json' => $properties]); 56 | } 57 | 58 | /** 59 | * Delete the comment. 60 | * 61 | * @param mixed $id 62 | * 63 | * @see https://developers.hubspot.com/docs/methods/comments/delete_comments_comment_id 64 | * 65 | * @return \SevenShores\Hubspot\Http\Response 66 | */ 67 | public function delete($id) 68 | { 69 | $endpoint = "https://api.hubapi.com/comments/v3/comments/{$id}"; 70 | 71 | return $this->client->request('delete', $endpoint); 72 | } 73 | 74 | /** 75 | * Restores a previously deleted comment. 76 | * 77 | * @param mixed $id 78 | * 79 | * @see https://developers.hubspot.com/docs/methods/comments/post_comments_comment_id_restore_deleted 80 | * 81 | * @return \SevenShores\Hubspot\Http\Response 82 | */ 83 | public function restore($id) 84 | { 85 | $endpoint = "https://api.hubapi.com/comments/v3/comments/{$id}/restore"; 86 | 87 | return $this->client->request('post', $endpoint); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /tests/Integration/Resources/ContactListsTest.php: -------------------------------------------------------------------------------- 1 | resource->all(); 28 | 29 | $this->assertEquals(200, $response->getStatusCode()); 30 | } 31 | 32 | /** @test */ 33 | public function getAllStatic() 34 | { 35 | $response = $this->resource->getAllStatic(); 36 | 37 | $this->assertEquals(200, $response->getStatusCode()); 38 | } 39 | 40 | /** @test */ 41 | public function update() 42 | { 43 | $response = $this->resource->update($this->entity->listId, [ 44 | 'name' => 'New test name '.uniqid(), 45 | ]); 46 | 47 | $this->assertEquals(200, $response->getStatusCode()); 48 | } 49 | 50 | /** @test */ 51 | public function getById() 52 | { 53 | $response = $this->resource->getById($this->entity->listId); 54 | 55 | $this->assertEquals(200, $response->getStatusCode()); 56 | } 57 | 58 | /** @test */ 59 | public function getBatchByIds() 60 | { 61 | $list = $this->createEntity(); 62 | 63 | $ids = [ 64 | $this->entity->listId, 65 | $list->listId, 66 | ]; 67 | 68 | $response = $this->resource->getBatchByIds($ids); 69 | 70 | $this->assertEquals(200, $response->getStatusCode()); 71 | 72 | $this->resource->delete($list->listId); 73 | } 74 | 75 | /** @test */ 76 | public function contacts() 77 | { 78 | $response = $this->resource->contacts($this->entity->listId); 79 | 80 | $this->assertEquals(200, $response->getStatusCode()); 81 | } 82 | 83 | /** @test */ 84 | public function recentContacts() 85 | { 86 | $response = $this->resource->recentContacts($this->entity->listId); 87 | 88 | $this->assertEquals(200, $response->getStatusCode()); 89 | } 90 | 91 | /** @test */ 92 | public function delete() 93 | { 94 | $response = $this->resource->delete($this->entity->listId); 95 | 96 | $this->assertEquals(204, $response->getStatusCode()); 97 | 98 | $this->entity = null; 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /src/Resources/DealPipelines.php: -------------------------------------------------------------------------------- 1 | all 17 | * @deprecated 18 | * 19 | * @return mixed 20 | */ 21 | public function getAllPipelines() 22 | { 23 | $endpoint = 'https://api.hubapi.com/deals/v1/pipelines'; 24 | 25 | return $this->client->request('get', $endpoint); 26 | } 27 | 28 | /** 29 | * Get single pipeline by id. 30 | * 31 | * @param int $id 32 | * 33 | * @see https://developers.hubspot.com/docs/methods/deal-pipelines/get-deal-pipeline 34 | * @see CrmPipelines->all 35 | * @deprecated 36 | * 37 | * @return mixed 38 | */ 39 | public function getPipeline($id) 40 | { 41 | $endpoint = "https://api.hubapi.com/deals/v1/pipelines/{$id}"; 42 | 43 | return $this->client->request('get', $endpoint); 44 | } 45 | 46 | /** 47 | * Create a pipeline. 48 | * 49 | * @see https://developers.hubspot.com/docs/methods/deal-pipelines/create-deal-pipeline 50 | * @see CrmPipelines->create 51 | * @deprecated 52 | * 53 | * @return mixed 54 | */ 55 | public function create(array $pipeline) 56 | { 57 | $endpoint = 'https://api.hubapi.com/deals/v1/pipelines'; 58 | 59 | return $this->client->request('post', $endpoint, ['json' => $pipeline]); 60 | } 61 | 62 | /** 63 | * Update a pipeline. 64 | * 65 | * @param int $id 66 | * 67 | * @see https://developers.hubspot.com/docs/methods/deal-pipelines/update-deal-pipeline 68 | * @see CrmPipelines->update 69 | * @deprecated 70 | * 71 | * @return mixed 72 | */ 73 | public function update($id, array $pipeline) 74 | { 75 | $endpoint = "https://api.hubapi.com/deals/v1/pipelines/{$id}"; 76 | 77 | return $this->client->request('put', $endpoint, ['json' => $pipeline]); 78 | } 79 | 80 | /** 81 | * Delete a pipeline. 82 | * 83 | * @param int $id 84 | * 85 | * @see https://developers.hubspot.com/docs/methods/deals/delete_deal_pipeline 86 | * @see CrmPipelines->delete 87 | * @deprecated 88 | * 89 | * @return mixed 90 | */ 91 | public function delete($id) 92 | { 93 | $endpoint = "https://api.hubapi.com/deals/v1/pipelines/{$id}"; 94 | 95 | return $this->client->request('delete', $endpoint); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /src/Resources/Tickets.php: -------------------------------------------------------------------------------- 1 | client->request('post', $endpoint, $options); 21 | } 22 | 23 | /** 24 | * @param int $id the deal id 25 | * @param array $ticket the deal properties to update 26 | * 27 | * @return mixed 28 | */ 29 | public function update($id, array $ticket) 30 | { 31 | $endpoint = "https://api.hubapi.com/crm-objects/v1/objects/tickets/{$id}"; 32 | 33 | $options['json'] = $ticket; 34 | 35 | return $this->client->request('put', $endpoint, $options); 36 | } 37 | 38 | /** 39 | * @throws \SevenShores\Hubspot\Exceptions\BadRequest 40 | * 41 | * @return \Psr\Http\Message\ResponseInterface|\SevenShores\Hubspot\Http\Response 42 | */ 43 | public function all(array $params = []) 44 | { 45 | $endpoint = 'https://api.hubapi.com/crm-objects/v1/objects/tickets/paged'; 46 | 47 | $queryString = build_query_string($params); 48 | 49 | return $this->client->request('get', $endpoint, [], $queryString); 50 | } 51 | 52 | /** 53 | * @param int $id 54 | * 55 | * @return mixed 56 | */ 57 | public function delete($id) 58 | { 59 | $endpoint = "https://api.hubapi.com/crm-objects/v1/objects/tickets/{$id}"; 60 | 61 | return $this->client->request('delete', $endpoint); 62 | } 63 | 64 | /** 65 | * @param int $id 66 | * @param array $params Optional parameters ['properties', 'propertiesWithHistory', 'includeDeletes'] 67 | * 68 | * @throws \SevenShores\Hubspot\Exceptions\BadRequest 69 | * 70 | * @return mixed 71 | */ 72 | public function getById($id, array $params = []) 73 | { 74 | $endpoint = "https://api.hubapi.com/crm-objects/v1/objects/tickets/{$id}"; 75 | 76 | $queryString = build_query_string($params); 77 | 78 | return $this->client->request('get', $endpoint, [], $queryString); 79 | } 80 | 81 | /** 82 | * @param array $params Optional parameters ['timestamp', 'changeType', 'objectId'] 83 | * 84 | * @return mixed 85 | */ 86 | public function getChangelog(array $params = []) 87 | { 88 | $endpoint = 'https://api.hubapi.com/crm-objects/v1/change-log/tickets'; 89 | $queryString = build_query_string($params); 90 | 91 | return $this->client->request('get', $endpoint, [], $queryString); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /tests/Integration/Abstraction/PropertiesTestCase.php: -------------------------------------------------------------------------------- 1 | resource->all(); 16 | 17 | $this->assertEquals(200, $response->getStatusCode()); 18 | $this->assertGreaterThanOrEqual(1, count($response->getData())); 19 | } 20 | 21 | /** @test */ 22 | public function get() 23 | { 24 | $response = $this->resource->get($this->entity->name); 25 | 26 | $this->assertEquals(200, $response->getStatusCode()); 27 | $this->assertEquals($this->entity->label, $response->label); 28 | } 29 | 30 | /** @test */ 31 | public function create() 32 | { 33 | $this->assertEquals(200, $this->entity->getStatusCode()); 34 | $this->assertEquals($this->getData()['label'], $this->entity->label); 35 | } 36 | 37 | /** @test */ 38 | public function update() 39 | { 40 | $property = $this->getDataForUpdate(); 41 | 42 | $response = $this->resource->update($this->entity->name, $property); 43 | 44 | $this->assertEquals(200, $response->getStatusCode()); 45 | $this->assertEquals($property['label'], $response->label); 46 | } 47 | 48 | /** @test */ 49 | public function delete() 50 | { 51 | $response = $this->deleteEntity(); 52 | 53 | $this->assertEquals(204, $response->getStatusCode()); 54 | 55 | $this->entity = null; 56 | } 57 | 58 | /** 59 | * Creates a new company property. 60 | * 61 | * @return \SevenShores\Hubspot\Http\Response 62 | */ 63 | protected function createEntity() 64 | { 65 | return $this->resource->create($this->getData()); 66 | } 67 | 68 | /** 69 | * Delete a new company property. 70 | * 71 | * @return \SevenShores\Hubspot\Http\Response 72 | */ 73 | protected function deleteEntity() 74 | { 75 | return $this->resource->delete($this->entity->name); 76 | } 77 | 78 | protected function getData() 79 | { 80 | return [ 81 | 'name' => 'property'.uniqid(), 82 | 'label' => 'Custom property', 83 | 'description' => 'An Awesome Custom property', 84 | 'groupName' => $this->groupName, 85 | 'type' => 'string', 86 | 'fieldType' => 'text', 87 | 'formField' => true, 88 | 'displayOrder' => 6, 89 | 'options' => [], 90 | ]; 91 | } 92 | 93 | protected function getDataForUpdate() 94 | { 95 | $data = $this->getData(); 96 | 97 | unset($data['name']); 98 | $data['label'] = 'Updated '.$data['label']; 99 | 100 | return $data; 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/Resources/Webhooks.php: -------------------------------------------------------------------------------- 1 | client->request('get', $endpoint); 19 | } 20 | 21 | /** 22 | * Create a new subscription. 23 | * 24 | * @param int $app_id 25 | * @param array $subscription 26 | * 27 | * @return \SevenShores\Hubspot\Http\Response 28 | */ 29 | public function createSubscription($app_id, $subscription) 30 | { 31 | $endpoint = "https://api.hubapi.com/webhooks/v1/{$app_id}/subscriptions"; 32 | 33 | $options['json'] = $subscription; 34 | 35 | return $this->client->request('post', $endpoint, $options); 36 | } 37 | 38 | /** 39 | * Update a subscription. 40 | * 41 | * @param int $app_id 42 | * @param int $subscription_id 43 | * @param array $subscription 44 | * 45 | * @return \SevenShores\Hubspot\Http\Response 46 | */ 47 | public function updateSubscription($app_id, $subscription_id, $subscription) 48 | { 49 | $endpoint = "https://api.hubapi.com/webhooks/v1/{$app_id}/subscriptions/{$subscription_id}"; 50 | 51 | $options['json'] = $subscription; 52 | 53 | return $this->client->request('put', $endpoint, $options); 54 | } 55 | 56 | /** 57 | * Delete a subscription. 58 | * 59 | * @param int $app_id 60 | * @param int $subscription_id 61 | * 62 | * @return \SevenShores\Hubspot\Http\Response 63 | */ 64 | public function deleteSubscription($app_id, $subscription_id) 65 | { 66 | $endpoint = "https://api.hubapi.com/webhooks/v1/{$app_id}/subscriptions/{$subscription_id}"; 67 | 68 | return $this->client->request('delete', $endpoint); 69 | } 70 | 71 | /** 72 | * Get webhook settings. 73 | * 74 | * @param int $app_id 75 | * 76 | * @return \SevenShores\Hubspot\Http\Response 77 | */ 78 | public function viewSettings($app_id) 79 | { 80 | $endpoint = "https://api.hubapi.com/webhooks/v1/{$app_id}/settings"; 81 | 82 | return $this->client->request('get', $endpoint); 83 | } 84 | 85 | /** 86 | * Update webhook settings. 87 | * 88 | * @param int $app_id 89 | * @param array $settings 90 | * 91 | * @return \SevenShores\Hubspot\Http\Response 92 | */ 93 | public function updateSettings($app_id, $settings) 94 | { 95 | $endpoint = "https://api.hubapi.com/webhooks/v1/{$app_id}/settings"; 96 | 97 | $options['json'] = $settings; 98 | 99 | return $this->client->request('put', $endpoint, $options); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /tests/Integration/Resources/HubDBTest.php: -------------------------------------------------------------------------------- 1 | resource->tables(); 19 | 20 | $this->assertEquals(200, $response->getStatusCode()); 21 | $this->assertGreaterThanOrEqual(1, count($response->objects)); 22 | } 23 | 24 | /** 25 | * @test 26 | */ 27 | public function getTable() 28 | { 29 | $response = $this->resource->getTable($this->entity->id, $this->portalId); 30 | 31 | $this->assertEquals(200, $response->getStatusCode()); 32 | $this->assertContains($this->entity->id, $response->toArray()); 33 | } 34 | 35 | /** 36 | * @test 37 | */ 38 | public function createTable() 39 | { 40 | $this->assertEquals(200, $this->entity->getStatusCode()); 41 | } 42 | 43 | /** 44 | * @test 45 | */ 46 | public function cloneTable() 47 | { 48 | $response = $this->resource->cloneTable($this->entity->id, 'Cloned Table'); 49 | 50 | $this->assertEquals(200, $response->getStatusCode()); 51 | $this->assertContains('Cloned Table', $response->toArray()); 52 | 53 | $this->resource->deleteTable($response->id); 54 | } 55 | 56 | /** 57 | * @test 58 | */ 59 | public function updateTable() 60 | { 61 | $response = $this->resource->updateTable($this->entity->id, 'Updated Table'); 62 | 63 | $this->assertEquals(200, $response->getStatusCode()); 64 | $this->assertContains('Updated Table', $response->toArray()); 65 | } 66 | 67 | /** 68 | * @test 69 | */ 70 | public function deleteTable() 71 | { 72 | $response = $this->deleteEntity(); 73 | 74 | $this->assertEquals(204, $response->getStatusCode()); 75 | 76 | $this->entity = null; 77 | } 78 | 79 | /** 80 | * @test 81 | */ 82 | public function import() 83 | { 84 | $response = $this->resource->import( 85 | $this->entity->id, 86 | __DIR__.'/../../data/hubdb.csv', 87 | [ 88 | 'resetTable' => false, 89 | 'skipRows' => 1, 90 | 'format' => 'csv', 91 | 'columnMappings' => [ 92 | [ 93 | 'source' => 1, 94 | 'target' => 1, 95 | ], 96 | [ 97 | 'source' => 2, 98 | 'target' => 2, 99 | ], 100 | ], 101 | ] 102 | ); 103 | 104 | $this->assertEquals(200, $response->getStatusCode()); 105 | $this->assertEquals(2, $response->rowsImported); 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /tests/Integration/Abstraction/PropertyGroupsTestCase.php: -------------------------------------------------------------------------------- 1 | resource->getAllGroups(); 16 | 17 | $this->assertEquals(200, $response->getStatusCode()); 18 | $this->assertGreaterThanOrEqual(1, count($response->getData())); 19 | $this->assertObjectNotHasAttribute('properties', $response->getData()[0]); 20 | } 21 | 22 | /** @test */ 23 | public function allWithProperties() 24 | { 25 | $response = $this->resource->getAllGroups(true); 26 | 27 | $this->assertEquals(200, $response->getStatusCode()); 28 | $this->assertGreaterThanOrEqual(1, count($response->getData())); 29 | $this->assertObjectHasAttribute('properties', $response->getData()[0]); 30 | } 31 | 32 | /** @test */ 33 | public function getGroup() 34 | { 35 | if (!$this->getGroup) { 36 | return true; 37 | } 38 | $response = $this->resource->getGroup($this->entity->name); 39 | 40 | $this->assertEquals(200, $response->getStatusCode()); 41 | } 42 | 43 | /** @test */ 44 | public function create() 45 | { 46 | $this->assertEquals(200, $this->entity->getStatusCode()); 47 | $this->assertEquals('A New Property Group', $this->entity->displayName); 48 | } 49 | 50 | /** @test */ 51 | public function update() 52 | { 53 | $group = [ 54 | 'displayName' => 'An Updated Property Group', 55 | 'displayOrder' => 7, 56 | ]; 57 | 58 | $response = $this->resource->updateGroup($this->entity->name, $group); 59 | 60 | $this->assertEquals(200, $response->getStatusCode()); 61 | $this->assertEquals('An Updated Property Group', $response->displayName); 62 | } 63 | 64 | /** @test */ 65 | public function delete() 66 | { 67 | $response = $this->resource->deleteGroup($this->entity->name); 68 | 69 | $this->assertEquals(204, $response->getStatusCode()); 70 | 71 | $this->entity = null; 72 | } 73 | 74 | /** 75 | * Delete a new property group. 76 | * 77 | * @return \SevenShores\Hubspot\Http\Response 78 | */ 79 | protected function deleteEntity() 80 | { 81 | return $this->resource->deleteGroup($this->entity->name); 82 | } 83 | 84 | /** 85 | * Creates a new property group. 86 | * 87 | * @return \SevenShores\Hubspot\Http\Response 88 | */ 89 | protected function createEntity() 90 | { 91 | $data = [ 92 | 'name' => 'group'.uniqid(), 93 | 'displayName' => 'A New Property Group', 94 | 'displayOrder' => 7, 95 | ]; 96 | 97 | return $this->resource->createGroup($data); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/helpers.php: -------------------------------------------------------------------------------- 1 | $value) { 17 | if (empty($value)) { 18 | continue; 19 | } 20 | 21 | if (is_array($value)) { 22 | $query .= build_batch_query_string($key, $value, $encoding); 23 | 24 | continue; 25 | } 26 | 27 | $parameter = url_encode($key, $encoding); 28 | $propertyValue = is_bool($value) ? 'true' : url_encode($value, $encoding); 29 | $query .= "&{$parameter}={$propertyValue}"; 30 | } 31 | 32 | return $query ?: ''; 33 | } 34 | } 35 | 36 | if (!function_exists('build_batch_query_string')) { 37 | /** 38 | * Generate a query string for batch requests. 39 | * 40 | * @param string $key the name of the query variable 41 | * @param array $items an array of item values for the variable 42 | * @param int $encoding 43 | */ 44 | function build_batch_query_string($key, array $items, $encoding = PHP_QUERY_RFC3986): string 45 | { 46 | return array_reduce($items, function ($query, $item) use ($key, $encoding) { 47 | return $query.'&'.url_encode($key, $encoding).'='.url_encode($item, $encoding); 48 | }, ''); 49 | } 50 | } 51 | 52 | if (!function_exists('url_encode')) { 53 | /** 54 | * Url encode a string. 55 | * 56 | * @param string $value 57 | * @param int $encoding 58 | * 59 | * @return string 60 | */ 61 | function url_encode($value, $encoding = PHP_QUERY_RFC3986) 62 | { 63 | switch ($encoding) { 64 | case false: 65 | return $value; 66 | 67 | case PHP_QUERY_RFC3986: 68 | return rawurlencode($value); 69 | 70 | case PHP_QUERY_RFC1738: 71 | return urlencode($value); 72 | 73 | default: 74 | throw new \InvalidArgumentException('Invalid type'); 75 | } 76 | } 77 | } 78 | 79 | if (!function_exists('ms_timestamp')) { 80 | /** 81 | * Get a millisecond timestamp from a date or time. 82 | * 83 | * @param mixed $time 84 | * 85 | * @return int 86 | */ 87 | function ms_timestamp($time) 88 | { 89 | switch (true) { 90 | case $time instanceof \DateTime: 91 | return $time->getTimestamp() * 1000; 92 | 93 | case is_numeric($time) && 10 === strlen((string) $time): 94 | return $time * 1000; 95 | 96 | case is_string($time): 97 | return strtotime($time) * 1000; 98 | 99 | default: 100 | return $time; 101 | } 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /tests/Integration/Resources/DealPipelinesTest.php: -------------------------------------------------------------------------------- 1 | assertEquals(200, $this->entity->getStatusCode()); 36 | $this->assertCount(1, $this->entity->stages); 37 | } 38 | 39 | /** 40 | * @test 41 | */ 42 | public function getAllPipelines() 43 | { 44 | $response = $this->resource->getAllPipelines(); 45 | 46 | $this->assertEquals(200, $response->getStatusCode()); 47 | $this->assertGreaterThanOrEqual(1, count($response->getData())); 48 | } 49 | 50 | /** 51 | * @test 52 | */ 53 | public function getPipeline() 54 | { 55 | $response = $this->resource->getPipeline($this->entity->pipelineId); 56 | 57 | $this->assertEquals(200, $response->getStatusCode()); 58 | $this->assertEquals($this->entity->label, $response->label); 59 | $this->assertCount(1, $response->stages); 60 | } 61 | 62 | /** 63 | * @test 64 | */ 65 | public function update() 66 | { 67 | $newLabel = 'Updated pipeline'.uniqid(); 68 | $response = $this->resource->update($this->entity->pipelineId, [ 69 | 'label' => $newLabel, 70 | 'pipelineId' => $this->entity->pipelineId, 71 | 'stages' => [ 72 | [ 73 | 'label' => 'new stage', 74 | ], 75 | ], 76 | ]); 77 | 78 | $this->assertEquals(200, $response->getStatusCode()); 79 | $this->assertSame($newLabel, $response->label); 80 | } 81 | 82 | /** @test */ 83 | public function delete() 84 | { 85 | $response = $this->deleteEntity(); 86 | 87 | $this->assertSame(204, $response->getStatusCode()); 88 | 89 | $this->entity = null; 90 | } 91 | 92 | protected function createEntity() 93 | { 94 | return $this->resource->create([ 95 | 'label' => 'New Business Pipeline'.uniqid(), 96 | 'displayOrder' => 5, 97 | 'stages' => [ 98 | [ 99 | 'label' => 'Initial Stage', 100 | 'displayOrder' => 0, 101 | 'probability' => 0.3, 102 | ], 103 | ], 104 | ]); 105 | } 106 | 107 | protected function deleteEntity() 108 | { 109 | return $this->resource->delete($this->entity->pipelineId); 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /tests/Integration/Abstraction/CrmPipelinesTestCase.php: -------------------------------------------------------------------------------- 1 | resource)) { 31 | $this->resource = new $this->resourceClass($this->getClient(), $this->type); 32 | } 33 | sleep(1); 34 | 35 | parent::setUp(); 36 | } 37 | 38 | /** @test */ 39 | public function getAllPipelinesTest() 40 | { 41 | $response = $this->resource->all(); 42 | 43 | $this->assertEquals(200, $response->getStatusCode()); 44 | } 45 | 46 | /** @test */ 47 | public function getAllPipelinesIncludingDeleted() 48 | { 49 | $response = $this->resource->all(['includeInactive' => 'INCLUDE_DELETED']); 50 | 51 | $this->assertEquals(200, $response->getStatusCode()); 52 | } 53 | 54 | /** @test */ 55 | public function createPipeline() 56 | { 57 | $this->assertEquals(200, $this->entity->getStatusCode()); 58 | } 59 | 60 | /** @test */ 61 | public function updatePipeline() 62 | { 63 | $response = $this->resource->update( 64 | $this->entity->pipelineId, 65 | $this->getData('Updated '.$this->type.' Pipeline') 66 | ); 67 | 68 | $this->assertEquals(200, $response->getStatusCode()); 69 | } 70 | 71 | /** @test */ 72 | public function deletePipeline() 73 | { 74 | $response = $this->deleteEntity(); 75 | 76 | $this->assertEquals(204, $response->getStatusCode()); 77 | 78 | $this->entity = null; 79 | } 80 | 81 | protected function createEntity() 82 | { 83 | return $this->resource->create($this->getData()); 84 | } 85 | 86 | protected function deleteEntity() 87 | { 88 | return $this->resource->delete($this->entity->pipelineId); 89 | } 90 | 91 | protected function getData(string $label = null) 92 | { 93 | if (is_null($label)) { 94 | $label = 'Demo '.$this->type.' Pipeline'; 95 | } 96 | 97 | return [ 98 | 'label' => $label.' '.uniqid(), 99 | 'displayOrder' => 1, 100 | 'active' => true, 101 | 'stages' => [ 102 | [ 103 | 'label' => 'Demo Stage', 104 | 'displayOrder' => 1, 105 | 'metadata' => [ 106 | 'probability' => 0.5, 107 | ], 108 | ], 109 | ], 110 | ]; 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /tests/Integration/Resources/BlogCommentsTest.php: -------------------------------------------------------------------------------- 1 | blogPostsResource = new BlogPosts(new Client(['key' => getenv($this->key)])); 39 | 40 | parent::setUp(); 41 | } 42 | 43 | public function tearDown(): void 44 | { 45 | parent::tearDown(); 46 | if (!empty($this->post)) { 47 | $this->deletePost(); 48 | } 49 | } 50 | 51 | /** @test */ 52 | public function all() 53 | { 54 | $response = $this->resource->all(); 55 | 56 | $this->assertEquals(200, $response->getStatusCode()); 57 | } 58 | 59 | /** @test */ 60 | public function getById() 61 | { 62 | $response = $this->resource->getById($this->entity->id); 63 | 64 | $this->assertEquals(200, $response->getStatusCode()); 65 | } 66 | 67 | /** @test */ 68 | public function create() 69 | { 70 | $this->assertEquals(200, $this->entity->getStatusCode()); 71 | } 72 | 73 | /** @test */ 74 | public function delete() 75 | { 76 | $response = $this->deleteEntity(); 77 | 78 | $this->assertEquals(204, $response->getStatusCode()); 79 | 80 | $this->entity = null; 81 | } 82 | 83 | /** @test */ 84 | public function restore() 85 | { 86 | $this->deleteEntity(); 87 | 88 | $response = $this->resource->restore($this->entity->id); 89 | 90 | $this->assertEquals(204, $response->getStatusCode()); 91 | } 92 | 93 | protected function createEntity() 94 | { 95 | $this->post = $this->createPost($this->blogPostsResource); 96 | 97 | sleep(1); 98 | 99 | return $this->resource->create([ 100 | 'comment' => 'This is a test blog comment', 101 | 'contentId' => $this->post->id, 102 | 'collectionId' => $this->blogId, 103 | 'contentTitle' => 'This is a test blog title', 104 | 'userEmail' => 'tester@gmail.com', 105 | 'userName' => 'tester', 106 | ]); 107 | } 108 | 109 | protected function deleteEntity() 110 | { 111 | return $this->resource->delete($this->entity->id); 112 | } 113 | 114 | protected function deletePost() 115 | { 116 | return $this->blogPostsResource->delete($this->post->id); 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /src/Resources/CrmPipelines.php: -------------------------------------------------------------------------------- 1 | objectType = $objectType; 20 | } 21 | 22 | /** 23 | * Get all of the pipelines for the specified object type. 24 | * This currently supports pipelines for deals and tickets. 25 | * 26 | * @param array $params | Array of optional parameter ['includeInactive' => 'EXCLUDE_DELETED' (default) | 'INCLUDE_DELETED'] 27 | * 28 | * @throws \SevenShores\Hubspot\Exceptions\BadRequest 29 | * 30 | * @see https://developers.hubspot.com/docs/methods/pipelines/get_pipelines_for_object_type 31 | * 32 | * @return \Psr\Http\Message\ResponseInterface|\SevenShores\Hubspot\Http\Response 33 | */ 34 | public function all(array $params = []) 35 | { 36 | $endpoint = "https://api.hubapi.com/crm-pipelines/v1/pipelines/{$this->objectType}"; 37 | 38 | return $this->client->request( 39 | 'get', 40 | $endpoint, 41 | [], 42 | build_query_string($params) 43 | ); 44 | } 45 | 46 | /** 47 | * Create a new pipeline. 48 | * 49 | * @param array $properties Array of pipeline properties 50 | * 51 | * @throws \SevenShores\Hubspot\Exceptions\BadRequest 52 | * 53 | * @see https://developers.hubspot.com/docs/methods/pipelines/create_new_pipeline 54 | * 55 | * @return \Psr\Http\Message\ResponseInterface|\SevenShores\Hubspot\Http\Response 56 | */ 57 | public function create(array $properties) 58 | { 59 | $endpoint = "https://api.hubapi.com/crm-pipelines/v1/pipelines/{$this->objectType}"; 60 | 61 | return $this->client->request('post', $endpoint, ['json' => $properties]); 62 | } 63 | 64 | /** 65 | * Update an existing pipeline. 66 | * 67 | * @throws \SevenShores\Hubspot\Exceptions\BadRequest 68 | * 69 | * @see https://developers.hubspot.com/docs/methods/pipelines/update_pipeline 70 | * 71 | * @return \Psr\Http\Message\ResponseInterface|\SevenShores\Hubspot\Http\Response 72 | */ 73 | public function update(string $id, array $properties) 74 | { 75 | $endpoint = "https://api.hubapi.com/crm-pipelines/v1/pipelines/{$this->objectType}/{$id}"; 76 | 77 | return $this->client->request('put', $endpoint, ['json' => $properties]); 78 | } 79 | 80 | /** 81 | * Delete an existing pipeline. 82 | * 83 | * @throws \SevenShores\Hubspot\Exceptions\BadRequest 84 | * 85 | * @see https://developers.hubspot.com/docs/methods/pipelines/delete_pipeline 86 | * 87 | * @return \Psr\Http\Message\ResponseInterface|\SevenShores\Hubspot\Http\Response 88 | */ 89 | public function delete(string $id) 90 | { 91 | $endpoint = "https://api.hubapi.com/crm-pipelines/v1/pipelines/{$this->objectType}/{$id}"; 92 | 93 | return $this->client->request('delete', $endpoint); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/RetryMiddlewareFactory.php: -------------------------------------------------------------------------------- 1 | = $maxRetries) { 69 | return false; 70 | } 71 | 72 | if ($response instanceof Response) { 73 | if (($response->getStatusCode() >= $from) && ($response->getStatusCode() <= $to)) { 74 | return true; 75 | } 76 | } 77 | 78 | return false; 79 | }; 80 | } 81 | 82 | public static function getRetryFunction(array $codes, int $maxRetries = 5) 83 | { 84 | return function ( 85 | $retries, 86 | Request $request, 87 | Response $response = null, 88 | RequestException $exception = null 89 | ) use ($codes, $maxRetries) { 90 | if ($retries >= $maxRetries) { 91 | return false; 92 | } 93 | 94 | if (($response instanceof Response) && in_array($response->getStatusCode(), $codes)) { 95 | return true; 96 | } 97 | 98 | return false; 99 | }; 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /tests/Integration/Resources/BlogAuthorsTest.php: -------------------------------------------------------------------------------- 1 | resource->all(); 20 | 21 | $this->assertEquals(200, $response->getStatusCode()); 22 | } 23 | 24 | /** @test */ 25 | public function allWithParams() 26 | { 27 | $response = $this->resource->all([ 28 | 'limit' => 2, 29 | 'offset' => 3, 30 | ]); 31 | 32 | $this->assertEquals(200, $response->getStatusCode()); 33 | $this->assertLessThanOrEqual(2, count($response->objects)); 34 | $this->assertGreaterThanOrEqual(3, $response->offset); 35 | } 36 | 37 | /** @test */ 38 | public function searchWithoutQueryAndParams() 39 | { 40 | $response = $this->resource->search(); 41 | 42 | $this->assertEquals(200, $response->getStatusCode()); 43 | } 44 | 45 | /** @test */ 46 | public function searchWithQueryAndWithoutParams() 47 | { 48 | $response = $this->resource->search('john-smith'); 49 | 50 | $this->assertEquals(200, $response->getStatusCode()); 51 | } 52 | 53 | /** @test */ 54 | public function searchWithQueryAndParams() 55 | { 56 | $response = $this->resource->search('john-smith', [ 57 | 'limit' => 5, 58 | ]); 59 | 60 | $this->assertEquals(200, $response->getStatusCode()); 61 | $this->assertLessThanOrEqual(5, count($response->objects)); 62 | } 63 | 64 | /** @test */ 65 | public function getById() 66 | { 67 | $response = $this->resource->getById($this->entity->id); 68 | 69 | $this->assertEquals(200, $response->getStatusCode()); 70 | } 71 | 72 | /** @test */ 73 | public function create() 74 | { 75 | $this->assertEquals(201, $this->entity->getStatusCode()); 76 | } 77 | 78 | /** @test */ 79 | public function update() 80 | { 81 | $response = $this->resource->update($this->entity->id, [ 82 | 'bio' => 'Lorem ipsum dolor sit amet.', 83 | 'website' => 'http://example.com', 84 | ]); 85 | 86 | $this->assertEquals(200, $response->getStatusCode()); 87 | } 88 | 89 | /** @test */ 90 | public function delete() 91 | { 92 | $response = $this->resource->delete($this->entity->id); 93 | 94 | $this->assertEquals(204, $response->getStatusCode()); 95 | 96 | $this->entity = null; 97 | } 98 | 99 | protected function createEntity() 100 | { 101 | return $this->resource->create([ 102 | 'fullName' => 'John Smith '.uniqid(), 103 | 'email' => 'john.smith'.uniqid().'@example.com', 104 | 'username' => 'john-smith', 105 | ]); 106 | } 107 | 108 | protected function deleteEntity() 109 | { 110 | $this->resource->delete($this->entity->id); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/Resources/EmailSubscription.php: -------------------------------------------------------------------------------- 1 | client->request( 24 | 'get', 25 | $endpoint, 26 | [], 27 | $this->getQueryString($portalId) 28 | ); 29 | } 30 | 31 | /** 32 | * View subscriptions timeline for a portal. 33 | * 34 | * @see https://developers.hubspot.com/docs/methods/email/get_subscriptions_timeline 35 | * 36 | * @param array $params Optional parameters 37 | * 38 | * @return \SevenShores\Hubspot\Http\Response 39 | */ 40 | public function subscriptionsTimeline(array $params = []) 41 | { 42 | $endpoint = 'https://api.hubapi.com/email/public/v1/subscriptions/timeline'; 43 | 44 | return $this->client->request( 45 | 'get', 46 | $endpoint, 47 | [], 48 | build_query_string($params) 49 | ); 50 | } 51 | 52 | /** 53 | * Get email subscription status for an email address. 54 | * 55 | * @see https://developers.hubspot.com/docs/methods/email/get_status 56 | * 57 | * @param string $email 58 | * @param int $portalId 59 | * 60 | * @return \SevenShores\Hubspot\Http\Response 61 | */ 62 | public function subscriptionStatus($email, $portalId = null) 63 | { 64 | $endpoint = "https://api.hubapi.com/email/public/v1/subscriptions/{$email}"; 65 | 66 | return $this->client->request( 67 | 'get', 68 | $endpoint, 69 | [], 70 | $this->getQueryString($portalId) 71 | ); 72 | } 73 | 74 | /** 75 | * Update email subscription status for an email address. 76 | * 77 | * @see https://developers.hubspot.com/docs/methods/email/update_status 78 | * 79 | * @param string $email 80 | * @param int $portalId 81 | * 82 | * @return \SevenShores\Hubspot\Http\Response 83 | */ 84 | public function updateSubscription($email, array $data = [], $portalId = null) 85 | { 86 | $endpoint = "https://api.hubapi.com/email/public/v1/subscriptions/{$email}"; 87 | 88 | return $this->client->request( 89 | 'put', 90 | $endpoint, 91 | ['json' => $data], 92 | $this->getQueryString($portalId) 93 | ); 94 | } 95 | 96 | /** 97 | * @param int $portalId 98 | * 99 | * @return string 100 | */ 101 | protected function getQueryString($portalId) 102 | { 103 | if (!empty($portalId)) { 104 | return build_query_string(['portalId' => $portalId]); 105 | } 106 | 107 | return null; 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /tests/unit/Exception/HubspotExceptionTest.php: -------------------------------------------------------------------------------- 1 | assertInstanceOf(HubspotException::class, $hubspotException); 33 | $this->assertNull($hubspotException->getResponse()); 34 | } 35 | 36 | /** @test */ 37 | public function createExceptionFromGuzzleClientException() 38 | { 39 | $e = ClientException::create( 40 | new Request( 41 | 'GET', 42 | sprintf('https://api.hubapi.com/deals/v1/deal/12345?access_token=%s', static::EXAMPLE_TOKEN) 43 | ), 44 | new Response( 45 | 400, 46 | [], 47 | Utils::streamFor('{"status":"error","message":"xyz"}') 48 | ) 49 | ); 50 | 51 | $hubspotException = BadRequest::create($e); 52 | 53 | $this->assertInstanceOf(BadRequest::class, $hubspotException); 54 | $this->assertStringNotContainsString(static::EXAMPLE_TOKEN, $hubspotException->getMessage()); 55 | $this->assertSame($e->getResponse(), $hubspotException->getResponse()); 56 | $this->assertSame('Client error: `GET https://api.hubapi.com/deals/v1/deal/12345?access_token=***` resulted in a `400 Bad Request` response: 57 | {"status":"error","message":"xyz"} 58 | ', $hubspotException->getMessage()); 59 | } 60 | 61 | /** @test */ 62 | public function createExceptionFromGuzzleServerException() 63 | { 64 | $e = ServerException::create( 65 | new Request( 66 | 'GET', 67 | sprintf('https://api.hubapi.com/deals/v1/deal/12345?hapikey=%s', static::EXAMPLE_TOKEN) 68 | ), 69 | new Response( 70 | 502, 71 | [], 72 | Utils::streamFor(' 73 | ') 74 | ) 75 | ); 76 | 77 | $hubspotException = HubspotException::create($e); 78 | 79 | $this->assertInstanceOf(HubspotException::class, $hubspotException); 80 | $this->assertStringNotContainsString(static::EXAMPLE_TOKEN, $hubspotException->getMessage()); 81 | $this->assertSame($e->getResponse(), $hubspotException->getResponse()); 82 | $this->assertSame('Server error: `GET https://api.hubapi.com/deals/v1/deal/12345?hapikey=***` resulted in a `502 Bad Gateway` response: 83 | 84 | 85 | ', $hubspotException->getMessage()); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /tests/Integration/Resources/BlogTopicsTest.php: -------------------------------------------------------------------------------- 1 | resource->all(); 28 | 29 | $this->assertEquals(200, $response->getStatusCode()); 30 | } 31 | 32 | /** @test */ 33 | public function allWithParams() 34 | { 35 | $response = $this->resource->all([ 36 | 'limit' => 2, 37 | 'offset' => 3, 38 | ]); 39 | 40 | $this->assertEquals(200, $response->getStatusCode()); 41 | $this->assertLessThanOrEqual(2, count($response->objects)); 42 | $this->assertGreaterThanOrEqual(3, $response->offset); 43 | } 44 | 45 | /** @test */ 46 | public function searchWithoutQueryAndParams() 47 | { 48 | $response = $this->resource->search(''); 49 | 50 | $this->assertEquals(200, $response->getStatusCode()); 51 | } 52 | 53 | /** @test */ 54 | public function searchWithQueryAndWithoutParams() 55 | { 56 | $response = $this->resource->search('Test'); 57 | 58 | $this->assertEquals(200, $response->getStatusCode()); 59 | } 60 | 61 | /** @test */ 62 | public function searchWithQueryAndParams() 63 | { 64 | $response = $this->resource->search('Test', [ 65 | 'limit' => 5, 66 | ]); 67 | 68 | $this->assertEquals(200, $response->getStatusCode()); 69 | $this->assertLessThanOrEqual(5, count($response->objects)); 70 | } 71 | 72 | /** @test */ 73 | public function getById() 74 | { 75 | $response = $this->resource->getById($this->entity->id); 76 | 77 | $this->assertEquals(200, $response->getStatusCode()); 78 | } 79 | 80 | /** @test */ 81 | public function create() 82 | { 83 | $this->assertEquals(201, $this->entity->getStatusCode()); 84 | } 85 | 86 | /** @test */ 87 | public function update() 88 | { 89 | $response = $this->resource->update($this->entity->id, [ 90 | 'name' => 'Topic Test '.uniqid().' Updated', 91 | 'description' => 'Topic Test '.uniqid().' Description Updated', 92 | ]); 93 | 94 | $this->assertEquals(200, $response->getStatusCode()); 95 | } 96 | 97 | /** @test */ 98 | public function delete() 99 | { 100 | $response = $this->deleteEntity(); 101 | 102 | $this->assertEquals(204, $response->getStatusCode()); 103 | 104 | $this->entity = null; 105 | } 106 | 107 | protected function createEntity() 108 | { 109 | return $this->resource->create([ 110 | 'name' => 'Topic Test '.uniqid(), 111 | 'description' => 'Topic Test '.uniqid().' Description', 112 | ]); 113 | } 114 | 115 | protected function deleteEntity() 116 | { 117 | return $this->resource->delete($this->entity->id); 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | We love pull requests from everyone. By participating in this project, you 4 | agree to not be a jerk. 5 | 6 | ## Getting Started 7 | 8 | - Fork, then clone the repo: 9 | ``` 10 | git clone git@github.com:your-username/hubspot-php.git 11 | ``` 12 | 13 | - Set up your machine: 14 | ``` 15 | composer install 16 | ``` 17 | 18 | - Make your change. Add test for your changes. Make the tests pass, e.g.: 19 | ``` 20 | vendor/bin/phpunit tests/integration/Resources/TimelineTest 21 | ``` 22 | 23 | - Push to your fork and [submit a pull request][pr]. 24 | 25 | [pr]: https://github.com/ryanwinchester/hubspot-php/compare/ 26 | 27 | At this point you're waiting on us. We like to at least comment on pull requests 28 | within three business days (and, typically, one business day). We may suggest 29 | some changes or improvements or alternatives. 30 | 31 | Some things that will increase the chance that your pull request is accepted: 32 | 33 | * Write tests. 34 | * Follow PSR-2 [style guide][style]. 35 | * Write a [good commit message][commit]. 36 | 37 | [style]: https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md 38 | [commit]: http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html 39 | 40 | ## Adding a new Endpoint 41 | 42 | This is actually pretty easy. 43 | 44 | - Create a new Class in `src/Resources` that extends `Resource`. 45 | - Check existing classes for examples, it is pretty simple. 46 | - Add a method for each endpoint with a name that matches the endpoint url. 47 | - Make **required** parameters separate method arguments and *optional* parameters part of a `$params` array 48 | 49 | Examples of a good endpoint method: 50 | 51 | ```php 52 | /** 53 | * Create a contact property. 54 | * 55 | * Create a property on every contact object to store a specific piece of data. In the example below, 56 | * we want to store an invoice number on a separate field on deals. 57 | * 58 | * @see http://developers.hubspot.com/docs/methods/contacts/v2/create_contacts_property 59 | * 60 | * @param array $property 61 | * @return \SevenShores\Hubspot\Http\Response 62 | */ 63 | function create($property) 64 | { 65 | $endpoint = "https://api.hubapi.com/contacts/v2/properties"; 66 | 67 | $options['json'] = $property; 68 | 69 | return $this->client->request('post', $endpoint, $options); 70 | } 71 | ``` 72 | 73 | ```php 74 | /** 75 | * For a given portal, return all contacts that have been created in the portal. 76 | * 77 | * A paginated list of contacts will be returned to you, with a maximum of 100 contacts per page. 78 | * 79 | * Please Note: There are 2 fields here to pay close attention to: the "has-more" field that will let you know 80 | * whether there are more contacts that you can pull from this portal, and the "vid-offset" field which will let 81 | * you know where you are in the list of contacts. You can then use the "vid-offset" field in the "vidOffset" 82 | * parameter described below. 83 | * 84 | * @see http://developers.hubspot.com/docs/methods/contacts/get_contacts 85 | * 86 | * @param array $params Array of optional parameters ['count', 'property', 'vidOffset'] 87 | * @return \SevenShores\Hubspot\Http\Response 88 | */ 89 | function all($params = []) 90 | { 91 | $endpoint = "https://api.hubapi.com/contacts/v1/lists/all/contacts/all"; 92 | 93 | $queryString = build_query_string($params); 94 | 95 | return $this->client->request('get', $endpoint, [], $queryString); 96 | } 97 | ``` 98 | -------------------------------------------------------------------------------- /tests/spec/FactorySpec.php: -------------------------------------------------------------------------------- 1 | beConstructedThrough('create', ['demo']); 12 | } 13 | 14 | public function it_is_initializable() 15 | { 16 | $this->shouldHaveType('SevenShores\Hubspot\Factory'); 17 | } 18 | 19 | public function it_creates_a_blogs_api_class() 20 | { 21 | $this->blogs()->shouldHaveType('SevenShores\Hubspot\Resources\Blogs'); 22 | } 23 | 24 | public function it_creates_a_blogAuthors_api_class() 25 | { 26 | $this->blogAuthors()->shouldHaveType('SevenShores\Hubspot\Resources\BlogAuthors'); 27 | } 28 | 29 | public function it_creates_a_blogPosts_api_class() 30 | { 31 | $this->blogPosts()->shouldHaveType('SevenShores\Hubspot\Resources\BlogPosts'); 32 | } 33 | 34 | public function it_creates_a_blogTopics_api_class() 35 | { 36 | $this->blogTopics()->shouldHaveType('SevenShores\Hubspot\Resources\BlogTopics'); 37 | } 38 | 39 | public function it_creates_a_contacts_api_class() 40 | { 41 | $this->contacts()->shouldHaveType('SevenShores\Hubspot\Resources\Contacts'); 42 | } 43 | 44 | public function it_creates_a_contactLists_api_class() 45 | { 46 | $this->contactLists()->shouldHaveType('SevenShores\Hubspot\Resources\ContactLists'); 47 | } 48 | 49 | public function it_creates_a_contactProperties_api_class() 50 | { 51 | $this->contactProperties()->shouldHaveType('SevenShores\Hubspot\Resources\ContactProperties'); 52 | } 53 | 54 | public function it_creates_a_email_api_class() 55 | { 56 | $this->emailSubscription()->shouldHaveType('SevenShores\Hubspot\Resources\EmailSubscription'); 57 | } 58 | 59 | public function it_creates_a_emailEvents_api_class() 60 | { 61 | $this->emailEvents()->shouldHaveType('SevenShores\Hubspot\Resources\EmailEvents'); 62 | } 63 | 64 | public function it_creates_a_files_api_class() 65 | { 66 | $this->files()->shouldHaveType('SevenShores\Hubspot\Resources\Files'); 67 | } 68 | 69 | public function it_creates_a_forms_api_class() 70 | { 71 | $this->forms()->shouldHaveType('SevenShores\Hubspot\Resources\Forms'); 72 | } 73 | 74 | public function it_creates_a_keywords_api_class() 75 | { 76 | $this->keywords()->shouldHaveType('SevenShores\Hubspot\Resources\Keywords'); 77 | } 78 | 79 | public function it_creates_a_pages_api_class() 80 | { 81 | $this->pages()->shouldHaveType('SevenShores\Hubspot\Resources\Pages'); 82 | } 83 | 84 | public function it_creates_a_socialMedia_api_class() 85 | { 86 | $this->socialMedia()->shouldHaveType('SevenShores\Hubspot\Resources\SocialMedia'); 87 | } 88 | 89 | public function it_creates_a_workflows_api_class() 90 | { 91 | $this->workflows()->shouldHaveType('SevenShores\Hubspot\Resources\Workflows'); 92 | } 93 | 94 | public function it_creates_an_events_api_class() 95 | { 96 | $this->events()->shouldHaveType('SevenShores\Hubspot\Resources\Events'); 97 | } 98 | 99 | public function it_creates_a_company_properties_api_class() 100 | { 101 | $this->companyProperties()->shouldHaveType('SevenShores\Hubspot\Resources\CompanyProperties'); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | All notable changes to this project will be documented in this file. 3 | This project adheres to [Semantic Versioning](http://semver.org/). 4 | 5 | ## [Unreleased](https://github.com/HubSpot/hubspot-php/compare/v4.0.1...HEAD) 6 | 7 | ## [4.0.1] 8 | 9 | ### Changed 10 | - Fix composer json 11 | 12 | ## [4.0.0] 13 | 14 | ### Changed 15 | - Update Guzzle version (^7.3) 16 | - Update Php version (>=7.3) 17 | - Update Php cs fixer (^3.4) 18 | - Update Phpunit (^9.5) 19 | - Update Phpspec (^7.1) 20 | 21 | ## [3.2.1] 22 | 23 | ### Changed 24 | - Update type hinting 25 | - Update Readme 26 | - Fix Products (rename parameter for createBatch) 27 | 28 | ## [3.2.0] 29 | 30 | ### Changed 31 | - companies->getById($id) => companies->getById($id, array $params = []) 32 | - Remove unneeded defaults for files api 33 | 34 | ## [3.1.0] 35 | 36 | ### Added 37 | - contacts->addSecondaryEmail() 38 | - contacts->deleteSecondaryEmail() 39 | 40 | ## [3.0.1] 41 | 42 | ### Changed 43 | - Files::upload 44 | - Guzzle version 6 or 7 45 | 46 | ## [3.0.0] 47 | 48 | ### Changed 49 | - Comments to BlogComments 50 | - Deal create + update change params 51 | - BlogPosts::clonePost => BlogPosts::clone 52 | - BlogTopics::create remove name 53 | - contactsProperties getGroups => getAllGroups 54 | - CrmPipelines move object type to __construct 55 | - Up Guzzle version to 7 56 | - Up php version to 7.2 57 | 58 | ## [2.0.5] 59 | 60 | ### Changed 61 | - Added ability to remove list contacts by email address 62 | - minor changes 63 | 64 | ## [2.0.3] 65 | 66 | ### Added 67 | - Line Items Resource 68 | - Products Resource 69 | - Object Properties Resource 70 | 71 | ### Changed 72 | - Up php version to 7.0 73 | - Update Ecommerce Bridge to v2 74 | - Update Hub DB to v2 75 | - Update Form(only submit) to v3 76 | - Update Workflows to v3 77 | - Rename Email to EmailSubscriptions 78 | - Update many resources (Method's Visibility, Type Hinting etc) 79 | - Repair majority of tests 80 | - SingleEmail => TransactionEmail 81 | 82 | ## [1.0.0-rc.1] 83 | 84 | ### Added 85 | - [CHANGELOG](http://keepachangelog.com/) @ryanwinchester 86 | - Two new Exception classes @ryanwinchester 87 | 88 | ### Changed 89 | - Namespace renamed from `Fungku\HubSpot` to `SevenShores\Hubspot` @ryanwinchester 90 | - `Api` folder and namespace renamed to `Resources` @ryanwinchester 91 | - The factory `HubSpotService` renamed to `Factory` @ryanwinchester 92 | - The named static constructors in `Factory` were changed to `create()` and `createWithToken()` @ryanwinchester 93 | - The `Factory` constructor was also made public @ryanwinchester 94 | - Moved functionality of `Api` into `Client` and replaced `Api` with `Resource` @ryanwinchester 95 | - `Client` is now constructed with a configuration array @ryanwinchester 96 | - Removed `$base_url` in favour of putting the whole endpoint url in the resource methods. @ryanwinchester 97 | - Optional `HUBSPOT_API_KEY` environment variable changed to `HUBSPOT_SECRET` @ryanwinchester 98 | - Made `$data` property of `Response` public. Because why not? @ryanwinchester 99 | 100 | ### Fixed 101 | - Trying to return a response with`RequestException` in the `Client`. It now re-throws a new `BadRequest` Exception. [#48](https://github.com/ryanwinchester/hubspot-php/issues/48) @ryanwinchester 102 | 103 | [Unreleased]: https://github.com/ryanwinchester/hubspot-php/compare/v1.0.0-rc.1...HEAD 104 | [1.0.0-rc.1]: https://github.com/ryanwinchester/hubspot-php/compare/v0.9.11...v1.0.0-rc.1 105 | -------------------------------------------------------------------------------- /src/Resources/EmailEvents.php: -------------------------------------------------------------------------------- 1 | client->request( 24 | 'get', 25 | $endpoint, 26 | [], 27 | build_query_string($params) 28 | ); 29 | } 30 | 31 | /** 32 | * Get campaign IDs with recent activity for a portal. 33 | * 34 | * @see https://developers.hubspot.com/docs/methods/email/get_campaigns 35 | * 36 | * @param array $params Optional parameters 37 | * 38 | * @return \SevenShores\Hubspot\Http\Response 39 | */ 40 | public function getCampaignIdsWithRecentActivity(array $params = []) 41 | { 42 | $endpoint = 'https://api.hubapi.com/email/public/v1/campaigns'; 43 | 44 | return $this->client->request( 45 | 'get', 46 | $endpoint, 47 | [], 48 | build_query_string($params) 49 | ); 50 | } 51 | 52 | /** 53 | * Get campaign data for a given campaign. 54 | * 55 | * @see https://developers.hubspot.com/docs/methods/email/get_campaign_data 56 | * 57 | * @param int $campaignId 58 | * @param int $applicationId 59 | * 60 | * @return \SevenShores\Hubspot\Http\Response 61 | */ 62 | public function getCampaignById($campaignId, $applicationId) 63 | { 64 | $endpoint = "https://api.hubapi.com/email/public/v1/campaigns/{$campaignId}"; 65 | 66 | return $this->client->request( 67 | 'get', 68 | $endpoint, 69 | [], 70 | build_query_string(['appId' => $applicationId]) 71 | ); 72 | } 73 | 74 | /** 75 | * Get email events for a campaign or recipient. 76 | * 77 | * @see https://developers.hubspot.com/docs/methods/email/get_events 78 | * 79 | * @param array $params Optional parameters 80 | * 81 | * @return \SevenShores\Hubspot\Http\Response 82 | */ 83 | public function all(array $params = []) 84 | { 85 | $endpoint = 'https://api.hubapi.com/email/public/v1/events'; 86 | 87 | return $this->client->request( 88 | 'get', 89 | $endpoint, 90 | [], 91 | build_query_string($params) 92 | ); 93 | } 94 | 95 | /** 96 | * Get event data for a specific event. 97 | * 98 | * @see https://developers.hubspot.com/docs/methods/email/get_event_by_id 99 | * 100 | * @param int $id The event ID 101 | * @param int $created Timestamp (milliseconds) when the event was created 102 | * 103 | * @return \SevenShores\Hubspot\Http\Response 104 | */ 105 | public function getById($id, $created) 106 | { 107 | $endpoint = "https://api.hubapi.com/email/public/v1/events/{$created}/{$id}"; 108 | 109 | return $this->client->request('get', $endpoint); 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /tests/unit/Support/QueryBuilderTest.php: -------------------------------------------------------------------------------- 1 | assertEquals($result, build_query_string($params)); 18 | } 19 | 20 | /** @test */ 21 | public function buildWithBatch() 22 | { 23 | $query = [ 24 | 'property' => [ 25 | 'firstname', 26 | 'lastname', 27 | ], 28 | ]; 29 | 30 | $queryString = build_query_string($query); 31 | 32 | $this->assertEquals('&property=firstname&property=lastname', $queryString); 33 | } 34 | 35 | /** @test */ 36 | public function buildBatch() 37 | { 38 | $ids = [10, 11, 12, 13, 14, 15]; 39 | 40 | $queryString = build_batch_query_string('id', $ids); 41 | 42 | $this->assertEquals('&id=10&id=11&id=12&id=13&id=14&id=15', $queryString); 43 | } 44 | 45 | /** @test */ 46 | public function buildNestedBatchWithEncodingRFC3986() 47 | { 48 | $query = [ 49 | 'email' => 'test@test.com', 50 | 'description' => 'two words', 51 | 'property' => [ 52 | 'firstname', 53 | 'lastname', 54 | ], 55 | ]; 56 | 57 | $queryString = build_query_string($query); 58 | 59 | $this->assertEquals( 60 | '&email=test%40test.com&description=two%20words&property=firstname&property=lastname', 61 | $queryString 62 | ); 63 | } 64 | 65 | /** @test */ 66 | public function buildNestedBatchWithEncodingRFC1738() 67 | { 68 | $query = [ 69 | 'email' => 'test@test.com', 70 | 'description' => 'two words', 71 | 'property' => [ 72 | 'firstname', 73 | 'lastname', 74 | ], 75 | ]; 76 | 77 | $queryString = build_query_string($query, PHP_QUERY_RFC1738); 78 | 79 | $this->assertEquals( 80 | '&email=test%40test.com&description=two+words&property=firstname&property=lastname', 81 | $queryString 82 | ); 83 | } 84 | 85 | /** @test */ 86 | public function encode() 87 | { 88 | $string = "I wan't this encoded!"; 89 | 90 | $queryString = url_encode($string); 91 | 92 | $this->assertEquals( 93 | 'I%20wan%27t%20this%20encoded%21', 94 | $queryString 95 | ); 96 | } 97 | 98 | /** @test */ 99 | public function encodeFalse() 100 | { 101 | $string = "I wan't this encoded!"; 102 | 103 | $queryString = url_encode($string, false); 104 | 105 | $this->assertEquals($string, $queryString); 106 | } 107 | 108 | public function buildDataProvider() 109 | { 110 | yield 'string' => [['firstname' => 'joe', 'lastname' => 'blo'], '&firstname=joe&lastname=blo']; 111 | yield 'int' => [['firstname' => 'joe', 'active' => 1], '&firstname=joe&active=1']; 112 | yield 'bool true' => [['firstname' => 'joe', 'active' => true], '&firstname=joe&active=true']; 113 | yield 'bool false' => [['firstname' => 'joe', 'active' => false], '&firstname=joe']; 114 | yield 'empty array' => [['firstname' => 'joe', 'property' => []], '&firstname=joe']; 115 | yield 'array' => [['firstname' => 'joe', 'property' => ['foo']], '&firstname=joe&property=foo']; 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /src/Resources/BlogAuthors.php: -------------------------------------------------------------------------------- 1 | client->request( 21 | 'get', 22 | $endpoint, 23 | [], 24 | build_query_string($params) 25 | ); 26 | } 27 | 28 | /** 29 | * Search blog authors. 30 | * 31 | * @param string $q Search query 32 | * @param array $params optional parameters 33 | * 34 | * @see https://developers.hubspot.com/docs/methods/blog/v3/search-blog-authors 35 | * 36 | * @return \SevenShores\Hubspot\Http\Response 37 | */ 38 | public function search($q = '', array $params = []) 39 | { 40 | $endpoint = 'https://api.hubapi.com/blogs/v3/blog-authors/search'; 41 | 42 | $params['q'] = $q; 43 | 44 | return $this->client->request( 45 | 'get', 46 | $endpoint, 47 | [], 48 | build_query_string($params) 49 | ); 50 | } 51 | 52 | /** 53 | * Get a specific blog author. 54 | * 55 | * @param int $id unique identifier for a blog author 56 | * 57 | * @see https://developers.hubspot.com/docs/methods/blog/v3/get-blog-author-by-id 58 | * 59 | * @return \SevenShores\Hubspot\Http\Response 60 | */ 61 | public function getById($id, array $params = []) 62 | { 63 | $endpoint = "https://api.hubapi.com/blogs/v3/blog-authors/{$id}"; 64 | 65 | return $this->client->request( 66 | 'get', 67 | $endpoint, 68 | [], 69 | build_query_string($params) 70 | ); 71 | } 72 | 73 | /** 74 | * Create a new blog author. 75 | * 76 | * @param array $options optional Parameters 77 | * 78 | * @see https://developers.hubspot.com/docs/methods/blog/v3/create-blog-author 79 | * 80 | * @return \SevenShores\Hubspot\Http\Response 81 | */ 82 | public function create(array $options = [], array $params = []) 83 | { 84 | $endpoint = 'https://api.hubapi.com/blogs/v3/blog-authors'; 85 | 86 | return $this->client->request( 87 | 'post', 88 | $endpoint, 89 | ['json' => $options], 90 | build_query_string($params) 91 | ); 92 | } 93 | 94 | /** 95 | * Update a blog author. 96 | * 97 | * @param int $id unique identifier for a blog author 98 | * @param array $params fields to update 99 | * 100 | * @see https://developers.hubspot.com/docs/methods/blog/v3/update-blog-author 101 | * 102 | * @return \SevenShores\Hubspot\Http\Response 103 | */ 104 | public function update($id, array $params = []) 105 | { 106 | $endpoint = "https://api.hubapi.com/blogs/v3/blog-authors/{$id}"; 107 | 108 | return $this->client->request('put', $endpoint, ['json' => $params]); 109 | } 110 | 111 | /** 112 | * Delete a blog author. 113 | * 114 | * @param int $id unique identifier for the blog author to delete 115 | * 116 | * @see https://developers.hubspot.com/docs/methods/blog/v3/delete-blog-author 117 | * 118 | * @return \SevenShores\Hubspot\Http\Response 119 | */ 120 | public function delete($id) 121 | { 122 | $endpoint = "https://api.hubapi.com/blogs/v3/blog-authors/{$id}"; 123 | 124 | return $this->client->request('delete', $endpoint); 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /tests/Integration/Resources/HubDBRowTest.php: -------------------------------------------------------------------------------- 1 | row = $this->createRow(); 22 | } 23 | 24 | /** 25 | * @test 26 | */ 27 | public function getRows() 28 | { 29 | $response = $this->resource->getRows($this->entity->id, $this->portalId, true); 30 | 31 | $this->assertEquals(200, $response->getStatusCode()); 32 | $this->assertGreaterThanOrEqual(1, $response->totalCount); 33 | } 34 | 35 | /** 36 | * @test 37 | */ 38 | public function addRow() 39 | { 40 | $this->assertEquals(200, $this->row->getStatusCode()); 41 | } 42 | 43 | /** 44 | * @test 45 | */ 46 | public function cloneRow() 47 | { 48 | $response = $this->resource->cloneRow($this->entity->id, $this->row->id); 49 | 50 | $this->assertEquals(200, $response->getStatusCode()); 51 | $this->assertContains('Test name', $response->toArray()); 52 | } 53 | 54 | /** 55 | * @test 56 | */ 57 | public function updateRow() 58 | { 59 | $response = $this->resource->updateRow( 60 | $this->entity->id, 61 | $this->row->id, 62 | [ 63 | $this->entity->columns[0]->id => 'Updated Test name', 64 | ] 65 | ); 66 | 67 | $this->assertEquals(200, $response->getStatusCode()); 68 | $this->assertContains('Updated Test name', $response->toArray()); 69 | } 70 | 71 | /** 72 | * @test 73 | */ 74 | public function deleteRow() 75 | { 76 | $response = $this->resource->deleteRow( 77 | $this->entity->id, 78 | $this->row->id 79 | ); 80 | 81 | $this->assertEquals(204, $response->getStatusCode()); 82 | } 83 | 84 | /** 85 | * @test 86 | */ 87 | public function updateCell() 88 | { 89 | $response = $this->resource->updateCell( 90 | $this->entity->id, 91 | $this->row->id, 92 | $this->entity->columns[0]->id, 93 | [ 94 | 'value' => 'Updated Test name', 95 | ] 96 | ); 97 | 98 | $this->assertEquals(200, $response->getStatusCode()); 99 | $this->assertContains('Updated Test name', $response->toArray()); 100 | } 101 | 102 | /** 103 | * @test 104 | */ 105 | public function deleteCell() 106 | { 107 | $response = $this->resource->deleteCell( 108 | $this->entity->id, 109 | $this->row->id, 110 | $this->entity->columns[0]->id 111 | ); 112 | 113 | $this->assertEquals(204, $response->getStatusCode()); 114 | } 115 | 116 | /** 117 | * @test 118 | */ 119 | public function publishDraftTable() 120 | { 121 | $response = $this->resource->publishDraftTable($this->entity->id); 122 | 123 | $this->assertEquals(200, $response->getStatusCode()); 124 | $this->assertContains($this->entity->name, $response->toArray()); 125 | } 126 | 127 | /** 128 | * @test 129 | */ 130 | public function revertDraftTable() 131 | { 132 | $response = $this->resource->revertDraftTable($this->entity->id); 133 | 134 | $this->assertEquals(200, $response->getStatusCode()); 135 | } 136 | 137 | protected function createRow() 138 | { 139 | return $this->resource->addRow($this->entity->id, [ 140 | $this->entity->columns[0]->id => 'Test name', 141 | $this->entity->columns[1]->id => 10, 142 | ]); 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /tests/Integration/Resources/CalendarEventsTest.php: -------------------------------------------------------------------------------- 1 | ownersResource = new Owners($this->getClient()); 39 | $response = $this->ownersResource->all(['email' => getenv('HUBSPOT_TEST_EMAIL')]); 40 | if (empty($response->getData())) { 41 | throw new Exception('Invalid Email (HUBSPOT_TEST_EMAIL)'); 42 | } 43 | $this->owner = $response->getData()[0]; 44 | sleep(1); 45 | 46 | parent::setUp(); 47 | } 48 | 49 | /** 50 | * @test 51 | */ 52 | public function createTask() 53 | { 54 | $this->assertSame(200, $this->entity->getStatusCode()); 55 | } 56 | 57 | /** 58 | * @test 59 | */ 60 | public function updateTask() 61 | { 62 | $response = $this->resource->updateTask($this->entity->id, [ 63 | 'name' => 'Another name', 64 | 'description' => 'Another description', 65 | ]); 66 | 67 | $this->assertSame(200, $response->getStatusCode()); 68 | } 69 | 70 | /** 71 | * @test 72 | */ 73 | public function getTaskById() 74 | { 75 | $response = $this->resource->getTaskById($this->entity->id); 76 | 77 | $this->assertSame(200, $response->getStatusCode()); 78 | $this->assertEquals($this->entity->name, $response->name); 79 | $this->assertEquals($this->entity->description, $response->description); 80 | $this->assertEquals($this->entity->ownerId, $response->ownerId); 81 | } 82 | 83 | /** @test */ 84 | public function deleteTask() 85 | { 86 | $response = $this->deleteEntity(); 87 | 88 | $this->assertEquals(204, $response->getStatusCode()); 89 | 90 | $this->entity = null; 91 | } 92 | 93 | /** @test */ 94 | public function all() 95 | { 96 | sleep(5); 97 | $startDate = $this->entity->eventDate - 60 * 60 * 1000; 98 | $endDate = $this->entity->eventDate + 60 * 60 * 1000; 99 | 100 | $response = $this->resource->all($startDate, $endDate); 101 | 102 | $this->assertEquals(200, $response->getStatusCode()); 103 | $this->assertGreaterThanOrEqual(1, count($response->getData())); 104 | } 105 | 106 | /** @test */ 107 | public function allTasks() 108 | { 109 | sleep(5); 110 | $startDate = $this->entity->eventDate - 60 * 60 * 1000; 111 | $endDate = $this->entity->eventDate + 60 * 60 * 1000; 112 | 113 | $response = $this->resource->allTasks($startDate, $endDate); 114 | 115 | $this->assertEquals(200, $response->getStatusCode()); 116 | $this->assertGreaterThanOrEqual(1, count($response->toArray())); 117 | } 118 | 119 | protected function createEntity() 120 | { 121 | return $this->resource->createTask([ 122 | 'eventDate' => strtotime('+1 day') * 1000, //timestamp in milliseconds 123 | 'eventType' => 'PUBLISHING_TASK', 124 | 'category' => 'EMAIL', 125 | 'state' => 'TODO', 126 | 'name' => 'Some task', 127 | 'description' => 'Very important task', 128 | 'ownerId' => $this->owner->ownerId, 129 | ]); 130 | } 131 | 132 | protected function deleteEntity() 133 | { 134 | return $this->resource->deleteTask($this->entity->id); 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /tests/Integration/Resources/EngagementsTest.php: -------------------------------------------------------------------------------- 1 | contactsResource = new Contacts($this->getClient()); 38 | 39 | $this->contact = $this->createContact(); 40 | sleep(1); 41 | 42 | parent::setUp(); 43 | } 44 | 45 | public function tearDown(): void 46 | { 47 | parent::tearDown(); 48 | if (!empty($this->contact)) { 49 | $this->deleteContact(); 50 | } 51 | } 52 | 53 | /** @test */ 54 | public function create() 55 | { 56 | $this->assertEquals(200, $this->entity->getStatusCode()); 57 | } 58 | 59 | /** @test */ 60 | public function update() 61 | { 62 | $response = $this->resource->update($this->entity->engagement->id, [ 63 | 'active' => true, 64 | 'ownerId' => 1, 65 | 'type' => 'NOTE', 66 | 'timestamp' => time(), 67 | ], [ 68 | 'body' => 'note body1', 69 | ]); 70 | 71 | $this->assertEquals(200, $response->getStatusCode()); 72 | } 73 | 74 | /** @test */ 75 | public function delete() 76 | { 77 | $response = $this->deleteEntity(); 78 | 79 | $this->assertEquals(204, $response->getStatusCode()); 80 | 81 | $this->entity = null; 82 | } 83 | 84 | /** @test */ 85 | public function get() 86 | { 87 | $response = $this->resource->get($this->entity->engagement->id); 88 | 89 | $this->assertEquals(200, $response->getStatusCode()); 90 | } 91 | 92 | /** @test */ 93 | public function all() 94 | { 95 | $response = $this->resource->all(); 96 | 97 | $this->assertEquals(200, $response->getStatusCode()); 98 | } 99 | 100 | /** @test */ 101 | public function recent() 102 | { 103 | $response = $this->resource->recent(); 104 | 105 | $this->assertEquals(200, $response->getStatusCode()); 106 | } 107 | 108 | /** @test */ 109 | public function getCallDispositions() 110 | { 111 | $response = $this->resource->getCallDispositions(); 112 | 113 | $this->assertEquals(200, $response->getStatusCode()); 114 | $this->assertCount(6, $response->getData()); 115 | } 116 | 117 | protected function createEntity() 118 | { 119 | return $this->resource->create([ 120 | 'active' => true, 121 | 'ownerId' => 1, 122 | 'type' => 'NOTE', 123 | 'timestamp' => time(), 124 | ], [ 125 | 'contactIds' => [$this->contact->vid], 126 | 'companyIds' => [], 127 | 'dealIds' => [], 128 | 'ownerIds' => [], 129 | ], [ 130 | 'body' => 'note body', 131 | ]); 132 | } 133 | 134 | protected function deleteEntity() 135 | { 136 | return $this->resource->delete($this->entity->engagement->id); 137 | } 138 | 139 | protected function createContact() 140 | { 141 | return $this->contactsResource->create([ 142 | ['property' => 'email', 'value' => 'rw_test'.uniqid().'@hubspot.com'], 143 | ['property' => 'firstname', 'value' => 'joe'], 144 | ['property' => 'lastname', 'value' => 'user'], 145 | ]); 146 | } 147 | 148 | protected function deleteContact() 149 | { 150 | return $this->contactsResource->delete($this->contact->vid); 151 | } 152 | } 153 | -------------------------------------------------------------------------------- /tests/Integration/Resources/FormsTest.php: -------------------------------------------------------------------------------- 1 | resource->all(); 23 | 24 | $this->assertEquals(200, $response->getStatusCode()); 25 | $this->assertGreaterThanOrEqual(1, count($response->getData())); 26 | } 27 | 28 | /** @test */ 29 | public function create() 30 | { 31 | $this->assertEquals(200, $this->entity->getStatusCode()); 32 | } 33 | 34 | /** @test */ 35 | public function update() 36 | { 37 | $response = $this->resource->update($this->entity->guid, [ 38 | 'name' => 'new name '.uniqid(), 39 | ]); 40 | 41 | $this->assertEquals(200, $response->getStatusCode()); 42 | } 43 | 44 | /** @test */ 45 | public function getById() 46 | { 47 | $response = $this->resource->getById($this->entity->guid); 48 | 49 | $this->assertEquals(200, $response->getStatusCode()); 50 | } 51 | 52 | /** @test */ 53 | public function delete() 54 | { 55 | $reponse = $this->deleteEntity(); 56 | 57 | $this->assertEquals(204, $reponse->getStatusCode()); 58 | 59 | $this->entity = null; 60 | } 61 | 62 | /** @test */ 63 | public function getFields() 64 | { 65 | $response = $this->resource->getFields($this->entity->guid); 66 | 67 | $this->assertEquals(200, $response->getStatusCode()); 68 | } 69 | 70 | /** @test */ 71 | public function getFieldByName() 72 | { 73 | $response = $this->resource->getFieldByName($this->entity->guid, 'firstname'); 74 | 75 | $this->assertEquals(200, $response->getStatusCode()); 76 | } 77 | 78 | /** @test */ 79 | public function submit() 80 | { 81 | $response = $this->resource->submit(getenv('HUBSPOT_TEST_PORTAL_ID'), $this->entity->guid, [ 82 | 'fields' => [ 83 | [ 84 | 'name' => 'firstname', 85 | 'value' => 'Test Name', 86 | ], 87 | ], 88 | ]); 89 | 90 | $this->assertEquals(200, $response->getStatusCode()); 91 | } 92 | 93 | // Lots of tests need an existing object to modify. 94 | protected function createEntity() 95 | { 96 | return $this->resource->create([ 97 | 'name' => 'Test Form '.uniqid(), 98 | 'action' => '', 99 | 'method' => 'POST', 100 | 'cssClass' => 'hs-form stacked', 101 | 'redirect' => '', 102 | 'submitText' => 'Sign Up', 103 | 'followUpId' => '', 104 | 'leadNurturingCampaignId' => '', 105 | 'notifyRecipients' => '', 106 | 'embeddedCode' => '', 107 | 'formFieldGroups' => [ 108 | 'fields' => [ 109 | [ 110 | 'name' => 'firstname', 111 | 'label' => 'First Name', 112 | 'description' => '', 113 | 'groupName' => 'contactinformation', 114 | 'type' => 'string', 115 | 'fieldType' => 'text', 116 | 'displayOrder' => 1, 117 | 'required' => true, 118 | 'enabled' => true, 119 | 'hidden' => false, 120 | 'defaultValue' => '', 121 | 'isSmartField' => false, 122 | 'validation' => [ 123 | 'name' => '', 124 | 'message' => '', 125 | ], 126 | ], 127 | ], 128 | 'default' => true, 129 | 'isSmartGroup' => false, 130 | ], 131 | ]); 132 | } 133 | 134 | protected function deleteEntity() 135 | { 136 | return $this->resource->delete($this->entity->guid); 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /src/Resources/OAuth2.php: -------------------------------------------------------------------------------- 1 | 'authorization_code', 46 | 'client_id' => $clientId, 47 | 'client_secret' => $clientSecret, 48 | 'redirect_uri' => $redirectURI, 49 | 'code' => $tokenCode, 50 | ]; 51 | 52 | $options['headers']['content-type'] = 'application/x-www-form-urlencoded'; 53 | 54 | return $this->client->request('post', $this->endpoint.'/token', $options, null, false); 55 | } 56 | 57 | /** 58 | * Get OAuth 2.0 Access Token and Refresh Tokens by using a refresh token 59 | * Note: Contrary to HubSpot documentation, $redirectURI is NOT required. 60 | * 61 | * @param string $clientId the Client ID of your app 62 | * @param string $clientSecret the Client Secret of your app 63 | * @param string $refreshToken the refresh token 64 | * 65 | * @throws BadRequest 66 | * 67 | * @return Response 68 | */ 69 | public function getTokensByRefresh($clientId, $clientSecret, $refreshToken) 70 | { 71 | $options['form_params'] = [ 72 | 'grant_type' => 'refresh_token', 73 | 'client_id' => $clientId, 74 | 'client_secret' => $clientSecret, 75 | 'refresh_token' => $refreshToken, 76 | ]; 77 | 78 | $options['headers']['content-type'] = 'application/x-www-form-urlencoded'; 79 | 80 | return $this->client->request('post', $this->endpoint.'/token', $options, null, false); 81 | } 82 | 83 | /** 84 | * Get Information for OAuth 2.0 Access Token. 85 | * 86 | * @param int $token the access token that you want to get the information for 87 | * 88 | * @throws BadRequest 89 | * 90 | * @return Response 91 | */ 92 | public function getAccessTokenInfo($token) 93 | { 94 | return $this->client->request('get', $this->endpoint."/access-tokens/{$token}", [], null, false); 95 | } 96 | 97 | /** 98 | * Get Information for OAuth 2.0 Refresh Token. 99 | * 100 | * @param int $token the refresh token that you want to get the information for 101 | * 102 | * @throws BadRequest 103 | * 104 | * @return Response 105 | */ 106 | public function getRefreshTokenInfo($token) 107 | { 108 | return $this->client->request('get', $this->endpoint."/refresh-tokens/{$token}", [], null, false); 109 | } 110 | 111 | /** 112 | * Delete OAuth 2.0 Refresh Token. 113 | * 114 | * @param int $token the refresh token that you want to delete 115 | * 116 | * @throws BadRequest 117 | * 118 | * @return Response 119 | */ 120 | public function deleteRefreshToken($token) 121 | { 122 | return $this->client->request('delete', $this->endpoint."/refresh-tokens/{$token}", [], null, false); 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /src/Resources/BlogTopics.php: -------------------------------------------------------------------------------- 1 | client->request( 21 | 'get', 22 | $endpoint, 23 | [], 24 | build_query_string($params) 25 | ); 26 | } 27 | 28 | /** 29 | * Search a topic by the query. $query will match name and slug partially. 30 | * 31 | * @param string $query Search query 32 | * @param array $params Array of optional parameters ['name','slug','limit', 'offset', 'active', 'blog'] 33 | * 34 | * @see https://developers.hubspot.com/docs/methods/blog/v3/search-blog-topics 35 | * 36 | * @return \SevenShores\Hubspot\Http\Response 37 | */ 38 | public function search($query, array $params = []) 39 | { 40 | $endpoint = 'https://api.hubapi.com/blogs/v3/topics/search'; 41 | 42 | $params['q'] = $query; 43 | 44 | return $this->client->request( 45 | 'get', 46 | $endpoint, 47 | [], 48 | build_query_string($params) 49 | ); 50 | } 51 | 52 | /** 53 | * Get a blog topic by ID. 54 | * 55 | * @param int $id 56 | * 57 | * @see https://developers.hubspot.com/docs/methods/blog/v3/get-blog-topic-by-id 58 | * 59 | * @return \SevenShores\Hubspot\Http\Response 60 | */ 61 | public function getById($id, array $params = []) 62 | { 63 | $endpoint = "https://api.hubapi.com/blogs/v3/topics/{$id}"; 64 | 65 | return $this->client->request( 66 | 'get', 67 | $endpoint, 68 | [], 69 | build_query_string($params) 70 | ); 71 | } 72 | 73 | /** 74 | * Create a new blog topic. 75 | * 76 | * @param array $prorerties Blog topic's fields 77 | * @param array $params Optional parametrs 78 | * 79 | * @see https://developers.hubspot.com/docs/methods/blog/v3/create-blog-topic 80 | * 81 | * @return \SevenShores\Hubspot\Http\Response 82 | */ 83 | public function create(array $prorerties, $params = []) 84 | { 85 | $endpoint = 'https://api.hubapi.com/blogs/v3/topics'; 86 | 87 | return $this->client->request( 88 | 'post', 89 | $endpoint, 90 | ['json' => $prorerties], 91 | build_query_string($params) 92 | ); 93 | } 94 | 95 | /** 96 | * Update a blog topic. 97 | * 98 | * @param int $id the blog topic id 99 | * @param array $prorerties the blog topic fields to update 100 | * @param array $params Optional parametrs 101 | * 102 | * @see https://developers.hubspot.com/docs/methods/blog/v3/update-topic 103 | * 104 | * @return \SevenShores\Hubspot\Http\Response 105 | */ 106 | public function update($id, array $prorerties = [], array $params = []) 107 | { 108 | $endpoint = "https://api.hubapi.com/blogs/v3/topics/{$id}"; 109 | 110 | return $this->client->request( 111 | 'put', 112 | $endpoint, 113 | ['json' => $prorerties], 114 | build_query_string($params) 115 | ); 116 | } 117 | 118 | /** 119 | * Delete a blog topic. 120 | * 121 | * @param int $id 122 | * 123 | * @see https://developers.hubspot.com/docs/methods/blog/v3/delete-blog-topic 124 | * 125 | * @return \SevenShores\Hubspot\Http\Response 126 | */ 127 | public function delete($id) 128 | { 129 | $endpoint = "https://api.hubapi.com/blogs/v3/topics/{$id}"; 130 | 131 | return $this->client->request('delete', $endpoint); 132 | } 133 | 134 | /** 135 | * Group blog topics. 136 | * 137 | * @param array $topicIds Array of topic ids 138 | * @param string $groupedTopicName New name of the group 139 | * @param array $params Optional parametrs 140 | * 141 | * @see https://developers.hubspot.com/docs/methods/blog/v3/group-blog-topics 142 | * 143 | * @return \SevenShores\Hubspot\Http\Response 144 | */ 145 | public function merge(array $topicIds, $groupedTopicName, array $params = []) 146 | { 147 | $endpoint = 'https://api.hubapi.com/blogs/v3/topics/group-topics'; 148 | 149 | return $this->client->request( 150 | 'post', 151 | $endpoint, 152 | ['json' => [ 153 | 'topicIds' => $topicIds, 154 | 'groupedTopicName' => $groupedTopicName, 155 | ], 156 | ] 157 | ); 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /src/Resources/Workflows.php: -------------------------------------------------------------------------------- 1 | client->request('get', $endpoint); 22 | } 23 | 24 | /** 25 | * Get a specific workflow. 26 | * 27 | * @see https://developers.hubspot.com/docs/methods/workflows/v3/get_workflow 28 | * 29 | * @param int $id 30 | * 31 | * @return \SevenShores\Hubspot\Http\Response 32 | */ 33 | public function getById($id, array $params = []) 34 | { 35 | $endpoint = "https://api.hubapi.com/automation/v3/workflows/{$id}"; 36 | 37 | return $this->client->request( 38 | 'get', 39 | $endpoint, 40 | [], 41 | build_query_string($params) 42 | ); 43 | } 44 | 45 | /** 46 | * Enroll a contact in a workflow. 47 | * 48 | * @see https://developers.hubspot.com/docs/methods/workflows/add_contact 49 | * 50 | * @param int $workflowId 51 | * @param string $email 52 | * 53 | * @return \SevenShores\Hubspot\Http\Response 54 | */ 55 | public function enrollContact($workflowId, $email) 56 | { 57 | $endpoint = "https://api.hubapi.com/automation/v2/workflows/{$workflowId}/enrollments/contacts/{$email}"; 58 | 59 | return $this->client->request('post', $endpoint); 60 | } 61 | 62 | /** 63 | * Create a new workflow. 64 | * 65 | * @see https://developers.hubspot.com/docs/methods/workflows/v3/create_workflow 66 | * 67 | * @param array $workflow The workflow properties 68 | * 69 | * @return \SevenShores\Hubspot\Http\Response 70 | */ 71 | public function create(array $workflow, array $params = []) 72 | { 73 | $endpoint = 'https://api.hubapi.com/automation/v3/workflows'; 74 | 75 | return $this->client->request( 76 | 'post', 77 | $endpoint, 78 | ['json' => $workflow], 79 | build_query_string($params) 80 | ); 81 | } 82 | 83 | /** 84 | * Delete a workflow. 85 | * 86 | * @see https://developers.hubspot.com/docs/methods/workflows/v3/delete_workflow 87 | * 88 | * @param int $id 89 | * 90 | * @return \SevenShores\Hubspot\Http\Response 91 | */ 92 | public function delete($id) 93 | { 94 | $endpoint = "https://api.hubapi.com/automation/v3/workflows/{$id}"; 95 | 96 | return $this->client->request('delete', $endpoint, []); 97 | } 98 | 99 | /** 100 | * Unenroll a contact from a workflow. 101 | * 102 | * @see https://developers.hubspot.com/docs/methods/workflows/remove_contact 103 | * 104 | * @param int $workflowId 105 | * @param string $email 106 | * 107 | * @return \SevenShores\Hubspot\Http\Response 108 | */ 109 | public function unenrollContact($workflowId, $email) 110 | { 111 | $endpoint = "https://api.hubapi.com/automation/v2/workflows/{$workflowId}/enrollments/contacts/{$email}"; 112 | 113 | return $this->client->request('delete', $endpoint); 114 | } 115 | 116 | /** 117 | * Get current enrollments for a contact. 118 | * 119 | * @see https://developers.hubspot.com/docs/methods/workflows/current_enrollments 120 | * 121 | * @param int $contactId 122 | * 123 | * @return \SevenShores\Hubspot\Http\Response 124 | */ 125 | public function currentEnrollments($contactId) 126 | { 127 | $endpoint = "https://api.hubapi.com/automation/v2/workflows/enrollments/contacts/{$contactId}"; 128 | 129 | return $this->client->request('get', $endpoint); 130 | } 131 | 132 | /** 133 | * Get performance statistics for a workflow. 134 | * 135 | * @see https://developers.hubspot.com/docs/methods/workflows/get_performance_statistics 136 | * 137 | * @param int $workflowId 138 | * @param int $startDate The start date for the data you want. Must be specified as a millisecond timestamp. 139 | * @param int $endDate The end date for the data you want. Must be specified as a millisecond timestamp. 140 | * @param string $bucket The time period used to group the data. Must be one of DAY, WEEK, or MONTH 141 | * 142 | * @return \SevenShores\Hubspot\Http\Response 143 | */ 144 | public function getPerformanceStatistics($workflowId, $startDate, $endDate, $bucket = 'DAY') 145 | { 146 | $endpoint = "https://api.hubapi.com/automation/v3/performance/workflow/{$workflowId}"; 147 | 148 | return $this->client->request( 149 | 'get', 150 | $endpoint, 151 | [], 152 | build_query_string([ 153 | 'start' => $startDate, 154 | 'end' => $endDate, 155 | 'bucket' => $bucket, 156 | ]) 157 | ); 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /tests/Integration/Resources/ProductsTest.php: -------------------------------------------------------------------------------- 1 | resource->all(); 30 | 31 | $this->assertEquals(200, $response->getStatusCode()); 32 | $this->assertGreaterThanOrEqual(1, count($response->objects)); 33 | } 34 | 35 | /** @test */ 36 | public function getById() 37 | { 38 | $response = $this->resource->getById($this->entity->objectId); 39 | 40 | $this->assertEquals(200, $response->getStatusCode()); 41 | } 42 | 43 | /** @test */ 44 | public function getBatchByIds() 45 | { 46 | $product = $this->createEntity(); 47 | 48 | $ids = [ 49 | $this->entity->objectId, 50 | $product->objectId, 51 | ]; 52 | 53 | $response = $this->resource->getBatchByIds($ids); 54 | 55 | $this->assertEquals(200, $response->getStatusCode()); 56 | $this->assertCount(2, $response->toArray()); 57 | 58 | $this->resource->delete($product->objectId); 59 | } 60 | 61 | /** @test */ 62 | public function create() 63 | { 64 | $this->assertEquals(200, $this->entity->getStatusCode()); 65 | } 66 | 67 | /** @test */ 68 | public function createBatch() 69 | { 70 | $response = $this->resource->createBatch([ 71 | $this->getData(), 72 | $this->getData(), 73 | ]); 74 | 75 | $this->assertEquals(200, $response->getStatusCode()); 76 | 77 | sleep(1); 78 | 79 | $this->resource->deleteBatch(array_map(function ($product) { 80 | return $product->objectId; 81 | }, array_values($response->getData()))); 82 | } 83 | 84 | /** @test */ 85 | public function update() 86 | { 87 | $response = $this->resource->update($this->entity->objectId, [ 88 | ['name' => 'name', 'value' => 'An updated product'], 89 | ]); 90 | 91 | $this->assertEquals(200, $response->getStatusCode()); 92 | } 93 | 94 | /** @test */ 95 | public function updateBatch() 96 | { 97 | $product = $this->createEntity(); 98 | 99 | $response = $this->resource->updateBatch([ 100 | [ 101 | 'objectId' => $this->entity->objectId, 102 | 'properties' => [ 103 | [ 104 | 'name' => 'price', 105 | 'value' => 85.00, 106 | ], 107 | [ 108 | 'name' => 'description', 109 | 'value' => 'This is an updated product, it\'s getting a price change.', 110 | ], 111 | ], 112 | ], 113 | [ 114 | 'objectId' => $product->objectId, 115 | 'properties' => [ 116 | [ 117 | 'name' => 'description', 118 | 'value' => 'Updated product name now with discount', 119 | ], 120 | [ 121 | 'name' => 'discount', 122 | 'value' => 20, 123 | ], 124 | ], 125 | ], 126 | ]); 127 | 128 | $this->assertEquals(200, $response->getStatusCode()); 129 | 130 | $this->resource->delete($product->objectId); 131 | } 132 | 133 | /** @test */ 134 | public function delete() 135 | { 136 | $response = $this->deleteEntity(); 137 | 138 | $this->assertEquals(204, $response->getStatusCode()); 139 | 140 | $this->entity = null; 141 | } 142 | 143 | /** @test */ 144 | public function deleteBatch() 145 | { 146 | $response = $this->resource->createBatch([ 147 | $this->getData(), 148 | $this->getData(), 149 | ]); 150 | 151 | sleep(1); 152 | 153 | $deleteResponse = $this->resource->deleteBatch(array_map(function ($product) { 154 | return $product->objectId; 155 | }, array_values($response->getData()))); 156 | 157 | $this->assertEquals(204, $deleteResponse->getStatusCode()); 158 | } 159 | 160 | /** @test */ 161 | public function getProductChanges() 162 | { 163 | $response = $this->resource->getProductChanges(); 164 | 165 | $this->assertEquals(200, $response->getStatusCode()); 166 | } 167 | 168 | protected function createEntity() 169 | { 170 | return $this->resource->create($this->getData()); 171 | } 172 | 173 | protected function deleteEntity() 174 | { 175 | return $this->resource->delete($this->entity->objectId); 176 | } 177 | } 178 | -------------------------------------------------------------------------------- /src/Resources/CrmAssociations.php: -------------------------------------------------------------------------------- 1 | client->request('get', $endpoint, [], $query_string); 72 | } 73 | 74 | /** 75 | * Associate CRM objects. 76 | * 77 | * @throws BadRequest 78 | * 79 | * @see https://developers.hubspot.com/docs/methods/crm-associations/associate-objects 80 | * 81 | * @return \Psr\Http\Message\ResponseInterface|\SevenShores\Hubspot\Http\Response 82 | */ 83 | public function create(array $association) 84 | { 85 | $endpoint = 'https://api.hubapi.com/crm-associations/v1/associations'; 86 | 87 | return $this->client->request('put', $endpoint, ['json' => $association]); 88 | } 89 | 90 | /** 91 | * Create multiple associations between CRM objects. 92 | * 93 | * @throws BadRequest 94 | * 95 | * @see https://developers.hubspot.com/docs/methods/crm-associations/batch-associate-objects 96 | * 97 | * @return \Psr\Http\Message\ResponseInterface|\SevenShores\Hubspot\Http\Response 98 | */ 99 | public function createBatch(array $associations) 100 | { 101 | $endpoint = 'https://api.hubapi.com/crm-associations/v1/associations/create-batch'; 102 | 103 | return $this->client->request( 104 | 'put', 105 | $endpoint, 106 | ['json' => $associations] 107 | ); 108 | } 109 | 110 | /** 111 | * Delete an association. 112 | * 113 | * @see https://developers.hubspot.com/docs/methods/crm-associations/delete-association 114 | * 115 | * @return \Psr\Http\Message\ResponseInterface|\SevenShores\Hubspot\Http\Response 116 | */ 117 | public function delete(array $association) 118 | { 119 | $endpoint = 'https://api.hubapi.com/crm-associations/v1/associations/delete'; 120 | 121 | return $this->client->request('put', $endpoint, ['json' => $association]); 122 | } 123 | 124 | /** 125 | * Delete multiple associations between CRM objects. 126 | * 127 | * @see https://developers.hubspot.com/docs/methods/crm-associations/batch-delete-associations 128 | * 129 | * @return \Psr\Http\Message\ResponseInterface|\SevenShores\Hubspot\Http\Response 130 | */ 131 | public function deleteBatch(array $associations) 132 | { 133 | $endpoint = 'https://api.hubapi.com/crm-associations/v1/associations/delete-batch'; 134 | 135 | return $this->client->request( 136 | 'put', 137 | $endpoint, 138 | ['json' => $associations] 139 | ); 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /src/Resources/Products.php: -------------------------------------------------------------------------------- 1 | client->request( 22 | 'get', 23 | $endpoint, 24 | [], 25 | build_query_string($params) 26 | ); 27 | } 28 | 29 | /** 30 | * Get a product by ID. 31 | * 32 | * @see https://developers.hubspot.com/docs/methods/products/get_product_by_id 33 | * 34 | * @param mixed $id 35 | * 36 | * @return \SevenShores\Hubspot\Http\Response 37 | */ 38 | public function getById($id, array $params = []) 39 | { 40 | $endpoint = "https://api.hubapi.com/crm-objects/v1/objects/products/{$id}"; 41 | 42 | return $this->client->request( 43 | 'get', 44 | $endpoint, 45 | [], 46 | build_query_string($params) 47 | ); 48 | } 49 | 50 | /** 51 | * Get a group of products by ID. 52 | * 53 | * @see https://developers.hubspot.com/docs/methods/products/batch-get-products 54 | * 55 | * @return \SevenShores\Hubspot\Http\Response 56 | */ 57 | public function getBatchByIds(array $ids, array $params = []) 58 | { 59 | $endpoint = 'https://api.hubapi.com/crm-objects/v1/objects/products/batch-read'; 60 | 61 | return $this->client->request( 62 | 'post', 63 | $endpoint, 64 | ['json' => ['ids' => $ids]], 65 | build_query_string($params) 66 | ); 67 | } 68 | 69 | /** 70 | * Create a product. 71 | * 72 | * @see https://developers.hubspot.com/docs/methods/products/create-product 73 | * 74 | * @return \SevenShores\Hubspot\Http\Response 75 | */ 76 | public function create(array $properties) 77 | { 78 | $endpoint = 'https://api.hubapi.com/crm-objects/v1/objects/products'; 79 | 80 | return $this->client->request( 81 | 'post', 82 | $endpoint, 83 | ['json' => $properties] 84 | ); 85 | } 86 | 87 | /** 88 | * Create a group of products. 89 | * 90 | * @see https://developers.hubspot.com/docs/methods/products/batch-create-products 91 | * 92 | * @return \SevenShores\Hubspot\Http\Response 93 | */ 94 | public function createBatch(array $products) 95 | { 96 | $endpoint = 'https://api.hubapi.com/crm-objects/v1/objects/products/batch-create'; 97 | 98 | return $this->client->request( 99 | 'post', 100 | $endpoint, 101 | ['json' => $products] 102 | ); 103 | } 104 | 105 | /** 106 | * Update a product. 107 | * 108 | * @see https://developers.hubspot.com/docs/methods/products/update-products 109 | * 110 | * @param mixed $id 111 | * 112 | * @return \SevenShores\Hubspot\Http\Response 113 | */ 114 | public function update($id, array $properties) 115 | { 116 | $endpoint = "https://api.hubapi.com/crm-objects/v1/objects/products/{$id}"; 117 | 118 | return $this->client->request( 119 | 'put', 120 | $endpoint, 121 | ['json' => $properties] 122 | ); 123 | } 124 | 125 | /** 126 | * Update a group of products. 127 | * 128 | * @see https://developers.hubspot.com/docs/methods/products/batch-update-products 129 | * 130 | * @return \SevenShores\Hubspot\Http\Response 131 | */ 132 | public function updateBatch(array $products) 133 | { 134 | $endpoint = 'https://api.hubapi.com/crm-objects/v1/objects/products/batch-update'; 135 | 136 | return $this->client->request( 137 | 'post', 138 | $endpoint, 139 | ['json' => $products] 140 | ); 141 | } 142 | 143 | /** 144 | * Delete a product. 145 | * 146 | * @see https://developers.hubspot.com/docs/methods/products/delete-product 147 | * 148 | * @param mixed $id 149 | * 150 | * @return \SevenShores\Hubspot\Http\Response 151 | */ 152 | public function delete($id) 153 | { 154 | $endpoint = "https://api.hubapi.com/crm-objects/v1/objects/products/{$id}"; 155 | 156 | return $this->client->request('delete', $endpoint); 157 | } 158 | 159 | /** 160 | * Delete a group of products. 161 | * 162 | * @see https://developers.hubspot.com/docs/methods/products/batch-delete-products 163 | * 164 | * @return \SevenShores\Hubspot\Http\Response 165 | */ 166 | public function deleteBatch(array $ids) 167 | { 168 | $endpoint = 'https://api.hubapi.com/crm-objects/v1/objects/products/batch-delete'; 169 | 170 | return $this->client->request( 171 | 'post', 172 | $endpoint, 173 | ['json' => ['ids' => $ids]] 174 | ); 175 | } 176 | 177 | /** 178 | * Get a log of changes for products. 179 | * 180 | * @see https://developers.hubspot.com/docs/methods/products/get-product-changes 181 | * 182 | * @return \SevenShores\Hubspot\Http\Response 183 | */ 184 | public function getProductChanges(array $params = []) 185 | { 186 | $endpoint = 'https://api.hubapi.com/crm-objects/v1/change-log/products'; 187 | 188 | return $this->client->request( 189 | 'get', 190 | $endpoint, 191 | [], 192 | build_query_string($params) 193 | ); 194 | } 195 | } 196 | -------------------------------------------------------------------------------- /src/Resources/CompanyProperties.php: -------------------------------------------------------------------------------- 1 | client->request('post', $endpoint, ['json' => $property]); 22 | } 23 | 24 | /** 25 | * Update the specified company-level property. This does not update the value on a specified company, but instead changes the definition of the company property. 26 | * 27 | * @see https://developers.hubspot.com/docs/methods/companies/update_company_property 28 | * 29 | * @return \SevenShores\Hubspot\Http\Response 30 | */ 31 | public function update(string $propertyName, array $property) 32 | { 33 | $endpoint = "https://api.hubapi.com/companies/v2/properties/named/{$propertyName}"; 34 | 35 | $property['name'] = $propertyName; 36 | 37 | return $this->client->request('put', $endpoint, ['json' => $property]); 38 | } 39 | 40 | /** 41 | * For a portal, delete an existing company property. 42 | * 43 | * @see https://developers.hubspot.com/docs/methods/companies/delete_company_property 44 | * 45 | * @param string $propertyName the API name of the property that you will be deleting 46 | * 47 | * @return \SevenShores\Hubspot\Http\Response 48 | */ 49 | public function delete(string $propertyName) 50 | { 51 | $endpoint = "https://api.hubapi.com/companies/v2/properties/named/{$propertyName}"; 52 | 53 | return $this->client->request('delete', $endpoint); 54 | } 55 | 56 | /** 57 | * Returns a JSON object representing the definition for a given company property. 58 | * 59 | * @see https://developers.hubspot.com/docs/methods/companies/get_company_property 60 | * 61 | * @param string $propertyName the API name of the property that you wish to see metadata for 62 | * 63 | * @return \SevenShores\Hubspot\Http\Response 64 | */ 65 | public function get(string $propertyName) 66 | { 67 | $endpoint = "https://api.hubapi.com/companies/v2/properties/named/{$propertyName}"; 68 | 69 | return $this->client->request('get', $endpoint); 70 | } 71 | 72 | /** 73 | * Returns all of the company properties, including their definition. 74 | * 75 | * @see https://developers.hubspot.com/docs/methods/companies/get_company_properties 76 | * 77 | * @return \SevenShores\Hubspot\Http\Response 78 | */ 79 | public function all() 80 | { 81 | $endpoint = 'https://api.hubapi.com/companies/v2/properties/'; 82 | 83 | return $this->client->request('get', $endpoint); 84 | } 85 | 86 | /** 87 | * Create a new company property group to gather like company-level data. 88 | * 89 | * @param array $group defines the group and any properties within it 90 | * 91 | * @see https://developers.hubspot.com/docs/methods/companies/create_company_property_group 92 | * 93 | * @return \SevenShores\Hubspot\Http\Response 94 | */ 95 | public function createGroup(array $group) 96 | { 97 | $endpoint = 'https://api.hubapi.com/companies/v2/groups/'; 98 | 99 | return $this->client->request('post', $endpoint, ['json' => $group]); 100 | } 101 | 102 | /** 103 | * Update a previously created company property group. 104 | * 105 | * @param string $groupName the API name of the property group that you will be updating 106 | * @param array $group defines the property group and any properties within it 107 | * 108 | * @see https://developers.hubspot.com/docs/methods/companies/update_company_property_group 109 | * 110 | * @return \SevenShores\Hubspot\Http\Response 111 | */ 112 | public function updateGroup(string $groupName, array $group) 113 | { 114 | $endpoint = "https://api.hubapi.com/companies/v2/groups/named/{$groupName}"; 115 | 116 | return $this->client->request('put', $endpoint, ['json' => $group]); 117 | } 118 | 119 | /** 120 | * Delete an existing company property group. 121 | * 122 | * @see https://developers.hubspot.com/docs/methods/companies/delete_company_property_group 123 | * 124 | * @param string $groupName the API name of the property group that you will be deleting 125 | * 126 | * @return \SevenShores\Hubspot\Http\Response 127 | */ 128 | public function deleteGroup(string $groupName) 129 | { 130 | $endpoint = "https://api.hubapi.com/companies/v2/groups/named/{$groupName}"; 131 | 132 | return $this->client->request('delete', $endpoint); 133 | } 134 | 135 | /** 136 | * Returns all of the company property groups for a given portal. 137 | * 138 | * @see https://developers.hubspot.com/docs/methods/companies/get_company_property_groups 139 | * 140 | * @param bool $includeProperties if true returns all of the properties for each company property group 141 | * 142 | * @return \SevenShores\Hubspot\Http\Response 143 | */ 144 | public function getAllGroups(bool $includeProperties = false) 145 | { 146 | $endpoint = 'https://api.hubapi.com/companies/v2/groups/'; 147 | 148 | $queryString = ''; 149 | 150 | if ($includeProperties) { 151 | $queryString = build_query_string(['includeProperties' => 'true']); 152 | } 153 | 154 | return $this->client->request('get', $endpoint, [], $queryString); 155 | } 156 | } 157 | -------------------------------------------------------------------------------- /src/Resources/LineItems.php: -------------------------------------------------------------------------------- 1 | client->request( 22 | 'get', 23 | $endpoint, 24 | [], 25 | build_query_string($params) 26 | ); 27 | } 28 | 29 | /** 30 | * Get a line item by ID. 31 | * 32 | * @param int $id 33 | * 34 | * @see https://developers.hubspot.com/docs/methods/line-items/get_line_item_by_id 35 | * 36 | * @return \SevenShores\Hubspot\Http\Response 37 | */ 38 | public function getById($id, array $params = []) 39 | { 40 | $endpoint = "https://api.hubapi.com/crm-objects/v1/objects/line_items/{$id}"; 41 | 42 | return $this->client->request( 43 | 'get', 44 | $endpoint, 45 | [], 46 | build_query_string($params) 47 | ); 48 | } 49 | 50 | /** 51 | * Get a group of line items by ID. 52 | * 53 | * @see https://developers.hubspot.com/docs/methods/line-items/batch-get-line-items 54 | * 55 | * @return \SevenShores\Hubspot\Http\Response 56 | */ 57 | public function getBatchByIds(array $ids, array $params = []) 58 | { 59 | $endpoint = 'https://api.hubapi.com/crm-objects/v1/objects/line_items/batch-read'; 60 | 61 | return $this->client->request( 62 | 'post', 63 | $endpoint, 64 | ['json' => ['ids' => $ids]], 65 | build_query_string($params) 66 | ); 67 | } 68 | 69 | /** 70 | * Create a line item. 71 | * 72 | * @see https://developers.hubspot.com/docs/methods/line-items/create-line-item 73 | * 74 | * @return \SevenShores\Hubspot\Http\Response 75 | */ 76 | public function create(array $properties) 77 | { 78 | $endpoint = 'https://api.hubapi.com/crm-objects/v1/objects/line_items'; 79 | 80 | return $this->client->request( 81 | 'post', 82 | $endpoint, 83 | ['json' => $properties] 84 | ); 85 | } 86 | 87 | /** 88 | * Create a group of line items. 89 | * 90 | * @see https://developers.hubspot.com/docs/methods/line-items/batch-create-line-items 91 | * 92 | * @return \SevenShores\Hubspot\Http\Response 93 | */ 94 | public function createBatch(array $lineItems) 95 | { 96 | $endpoint = 'https://api.hubapi.com/crm-objects/v1/objects/line_items/batch-create'; 97 | 98 | return $this->client->request( 99 | 'post', 100 | $endpoint, 101 | ['json' => $lineItems] 102 | ); 103 | } 104 | 105 | /** 106 | * Update a line item. 107 | * 108 | * @param int $id 109 | * 110 | * @see https://developers.hubspot.com/docs/methods/line-items/update-line-item 111 | * 112 | * @return \SevenShores\Hubspot\Http\Response 113 | */ 114 | public function update($id, array $properties) 115 | { 116 | $endpoint = "https://api.hubapi.com/crm-objects/v1/objects/line_items/{$id}"; 117 | 118 | return $this->client->request( 119 | 'put', 120 | $endpoint, 121 | ['json' => $properties] 122 | ); 123 | } 124 | 125 | /** 126 | * Update a group of line items. 127 | * 128 | * @see https://developers.hubspot.com/docs/methods/line-items/batch-update-line-items 129 | * 130 | * @return \SevenShores\Hubspot\Http\Response 131 | */ 132 | public function updateBatch(array $lineItems) 133 | { 134 | $endpoint = 'https://api.hubapi.com/crm-objects/v1/objects/line_items/batch-update'; 135 | 136 | return $this->client->request( 137 | 'post', 138 | $endpoint, 139 | ['json' => $lineItems] 140 | ); 141 | } 142 | 143 | /** 144 | * Delete a line item. 145 | * 146 | * @param int $id 147 | * 148 | * @see https://developers.hubspot.com/docs/methods/line-items/delete-line-item 149 | * 150 | * @return \SevenShores\Hubspot\Http\Response 151 | */ 152 | public function delete($id) 153 | { 154 | $endpoint = "https://api.hubapi.com/crm-objects/v1/objects/line_items/{$id}"; 155 | 156 | return $this->client->request('delete', $endpoint); 157 | } 158 | 159 | /** 160 | * Delete a group of line items. 161 | * 162 | * @see https://developers.hubspot.com/docs/methods/line-items/batch-delete-line-items 163 | * 164 | * @return \SevenShores\Hubspot\Http\Response 165 | */ 166 | public function deleteBatch(array $ids) 167 | { 168 | $endpoint = 'https://api.hubapi.com/crm-objects/v1/objects/line_items/batch-delete'; 169 | 170 | return $this->client->request( 171 | 'post', 172 | $endpoint, 173 | ['json' => ['ids' => $ids]] 174 | ); 175 | } 176 | 177 | /** 178 | * Get a log of changes for line items. 179 | * 180 | * @see https://developers.hubspot.com/docs/methods/line-items/get-line-item-changes 181 | * 182 | * @return \SevenShores\Hubspot\Http\Response 183 | */ 184 | public function getLineItemChanges(array $params = []) 185 | { 186 | $endpoint = 'https://api.hubapi.com/crm-objects/v1/change-log/line_items'; 187 | 188 | return $this->client->request( 189 | 'get', 190 | $endpoint, 191 | [], 192 | build_query_string($params) 193 | ); 194 | } 195 | } 196 | -------------------------------------------------------------------------------- /src/Resources/ObjectProperties.php: -------------------------------------------------------------------------------- 1 | objectType = $objectType; 20 | } 21 | 22 | /** 23 | * Get an Object Property. 24 | * 25 | * @param string $name the name of the property 26 | * 27 | * @return \SevenShores\Hubspot\Http\Response 28 | */ 29 | public function get(string $name) 30 | { 31 | $endpoint = "https://api.hubapi.com/properties/v2/{$this->objectType}/properties/named/{$name}"; 32 | 33 | return $this->client->request('get', $endpoint); 34 | } 35 | 36 | /** 37 | * Get all object properties. 38 | * 39 | * @see https://developers.hubspot.com/docs/methods/crm-properties/get-properties 40 | * 41 | * @return \SevenShores\Hubspot\Http\Response 42 | */ 43 | public function all() 44 | { 45 | $endpoint = "https://api.hubapi.com/properties/v2/{$this->objectType}/properties"; 46 | 47 | return $this->client->request('get', $endpoint); 48 | } 49 | 50 | /** 51 | * Create a new object property. 52 | * 53 | * @see https://developers.hubspot.com/docs/methods/crm-properties/create-property 54 | * 55 | * @return \SevenShores\Hubspot\Http\Response 56 | */ 57 | public function create(array $property) 58 | { 59 | $endpoint = "https://api.hubapi.com/properties/v2/{$this->objectType}/properties"; 60 | 61 | return $this->client->request('post', $endpoint, ['json' => $property]); 62 | } 63 | 64 | /** 65 | * Update an object property. 66 | * 67 | * Update a specified contact property. 68 | * 69 | * @see https://developers.hubspot.com/docs/methods/crm-properties/update-property 70 | * 71 | * @return \SevenShores\Hubspot\Http\Response 72 | */ 73 | public function update(string $name, array $property) 74 | { 75 | $endpoint = "https://api.hubapi.com/properties/v2/{$this->objectType}/properties/named/{$name}"; 76 | 77 | $property['name'] = $name; 78 | 79 | return $this->client->request('patch', $endpoint, ['json' => $property]); 80 | } 81 | 82 | /** 83 | * Delete an object property. 84 | * 85 | * @see https://developers.hubspot.com/docs/methods/crm-properties/delete-property 86 | * 87 | * @return \SevenShores\Hubspot\Http\Response 88 | */ 89 | public function delete(string $name) 90 | { 91 | $endpoint = "https://api.hubapi.com/properties/v2/{$this->objectType}/properties/named/{$name}"; 92 | 93 | return $this->client->request('delete', $endpoint); 94 | } 95 | 96 | /** 97 | * Get all object property groups. 98 | * 99 | * @see https://developers.hubspot.com/docs/methods/crm-properties/get-property-groups 100 | * 101 | * @return \SevenShores\Hubspot\Http\Response 102 | */ 103 | public function getAllGroups(bool $includeProperties = false) 104 | { 105 | $endpoint = "https://api.hubapi.com/properties/v2/{$this->objectType}/groups"; 106 | 107 | $queryString = ''; 108 | if ($includeProperties) { 109 | $queryString = build_query_string(['includeProperties' => 'true']); 110 | } 111 | 112 | return $this->client->request('get', $endpoint, [], $queryString); 113 | } 114 | 115 | /** 116 | * Get an object property group. 117 | * 118 | * @see https://developers.hubspot.com/docs/methods/crm-properties/get-property-groups 119 | * 120 | * @param mixed $name 121 | * 122 | * @return \SevenShores\Hubspot\Http\Response 123 | */ 124 | public function getGroup(string $name, bool $includeProperties = false) 125 | { 126 | $endpoint = "https://api.hubapi.com/properties/v2/{$this->objectType}/groups/named/{$name}"; 127 | 128 | $queryString = ''; 129 | if ($includeProperties) { 130 | $queryString = build_query_string(['includeProperties' => 'true']); 131 | } 132 | 133 | return $this->client->request('get', $endpoint, [], $queryString); 134 | } 135 | 136 | /** 137 | * Create an object property group. 138 | * 139 | * @see https://developers.hubspot.com/docs/methods/crm-properties/create-property-group 140 | * 141 | * @param array $group Group properties 142 | * 143 | * @return \SevenShores\Hubspot\Http\Response 144 | */ 145 | public function createGroup(array $group) 146 | { 147 | $endpoint = "https://api.hubapi.com/properties/v2/{$this->objectType}/groups"; 148 | 149 | return $this->client->request('post', $endpoint, ['json' => $group]); 150 | } 151 | 152 | /** 153 | * Update an object property group. 154 | * 155 | * @see https://developers.hubspot.com/docs/methods/crm-properties/udpate-property-group 156 | * 157 | * @return \SevenShores\Hubspot\Http\Response 158 | */ 159 | public function updateGroup(string $name, array $group) 160 | { 161 | $endpoint = "https://api.hubapi.com/properties/v2/{$this->objectType}/groups/named/{$name}"; 162 | 163 | $group['name'] = $name; 164 | 165 | return $this->client->request('put', $endpoint, ['json' => $group]); 166 | } 167 | 168 | /** 169 | * Delete a property group. 170 | * 171 | * Delete an existing contact property group. 172 | * 173 | * @see https://developers.hubspot.com/docs/methods/crm-properties/delete-property-group 174 | * 175 | * @return \SevenShores\Hubspot\Http\Response 176 | */ 177 | public function deleteGroup(string $name) 178 | { 179 | $endpoint = "https://api.hubapi.com/properties/v2/{$this->objectType}/groups/named/{$name}"; 180 | 181 | return $this->client->request('delete', $endpoint); 182 | } 183 | } 184 | --------------------------------------------------------------------------------