From fbfbe57e2280cb3824dd3c5c1e54c71b80f9ecb3 Mon Sep 17 00:00:00 2001 From: Michael Bausor Date: Fri, 10 Nov 2017 13:46:44 -0800 Subject: [PATCH 1/3] Add support for AnalyzeEntitySentiment --- src/Language/Annotation.php | 1 + .../Connection/ConnectionInterface.php | 6 ++ src/Language/Connection/Rest.php | 9 +++ src/Language/LanguageClient.php | 59 ++++++++++++++++ .../snippets/Language/LanguageClientTest.php | 26 +++++++ tests/system/Language/AnalyzeTest.php | 70 +++++++++++++++++++ tests/unit/Language/Connection/RestTest.php | 1 + tests/unit/Language/LanguageClientTest.php | 16 +++++ 8 files changed, 188 insertions(+) diff --git a/src/Language/Annotation.php b/src/Language/Annotation.php index f27c93fe490c..708b0f7448fe 100644 --- a/src/Language/Annotation.php +++ b/src/Language/Annotation.php @@ -31,6 +31,7 @@ * Annotations are returned by * {@see Google\Cloud\Language\LanguageClient::analyzeEntities()}, * {@see Google\Cloud\Language\LanguageClient::analyzeSentiment()}, + * {@see Google\Cloud\Language\LanguageClient::analyzeEntitySentiment()}, * {@see Google\Cloud\Language\LanguageClient::analyzeSyntax()} and * {@see Google\Cloud\Language\LanguageClient::annotateText()}. * diff --git a/src/Language/Connection/ConnectionInterface.php b/src/Language/Connection/ConnectionInterface.php index b4cc63e9e9e6..140909b190ee 100644 --- a/src/Language/Connection/ConnectionInterface.php +++ b/src/Language/Connection/ConnectionInterface.php @@ -35,6 +35,12 @@ public function analyzeEntities(array $args = []); */ public function analyzeSentiment(array $args = []); + /** + * @param array $args + * @return array + */ + public function analyzeEntitySentiment(array $args = []); + /** * @param array $args * @return array diff --git a/src/Language/Connection/Rest.php b/src/Language/Connection/Rest.php index 9864bbaffd23..4b6409a8c8c5 100644 --- a/src/Language/Connection/Rest.php +++ b/src/Language/Connection/Rest.php @@ -69,6 +69,15 @@ public function analyzeSentiment(array $args = []) return $this->send('documents', 'analyzeSentiment', $args); } + /** + * @param array $args + * @return array + */ + public function analyzeEntitySentiment(array $args = []) + { + return $this->send('documents', 'analyzeEntitySentiment',$args); + } + /** * @param array $args * @return array diff --git a/src/Language/LanguageClient.php b/src/Language/LanguageClient.php index d650e79a7e5a..4438601c7a06 100644 --- a/src/Language/LanguageClient.php +++ b/src/Language/LanguageClient.php @@ -218,6 +218,65 @@ public function analyzeSentiment($content, array $options = []) ); } + /** + * Finds entities in the text and analyzes sentiment associated with each + * entity and its mentions. + * + * Example: + * ``` + * $annotation = $language->analyzeEntitySentiment('Google Cloud Platform is a powerful tool.'); + * $entities = $annotation->entities(); + * + * echo 'Entity name: ' . $entities[0]['name'] . PHP_EOL; + * if ($entities[0]['sentiment']['score'] > 0) { + * echo 'This is a positive message.'; + * } + * ``` + * + * @codingStandardsIgnoreStart + * @see https://cloud.google.com/natural-language/docs/reference/rest/v1/documents/analyzeEntitySentiment Analyze Entity Sentiment API documentation + * @codingStandardsIgnoreEnd + * + * @param string|StorageObject $content The content to analyze. May be + * either a string of UTF-8 encoded content, a URI pointing to a + * Google Cloud Storage object in the format of + * `gs://{bucket-name}/{object-name}` or a + * {@see Google\Cloud\Storage\StorageObject}. + * @param array $options [optional] { + * Configuration options. + * + * @type bool $detectGcsUri When providing $content as a string, this + * flag determines whether or not to attempt to detect if the + * string represents a Google Cloud Storage URI in the format of + * `gs://{bucket-name}/{object-name}`. **Defaults to** `true`. + * @type string $type The document type. Acceptable values are + * `PLAIN_TEXT` or `HTML`. **Defaults to** `"PLAIN_TEXT"`. + * @type string $language The language of the document. Both ISO + * (e.g., en, es) and BCP-47 (e.g., en-US, es-ES) language codes + * are accepted. If no value is provided, the language will be + * detected by the service. + * @type string $encodingType The text encoding type used by the API to + * calculate offsets. Acceptable values are `"NONE"`, `"UTF8"`, + * `"UTF16"` and `"UTF32"`. **Defaults to** `"UTF8"`. Please note + * the following behaviors for the encoding type setting: `"NONE"` + * will return a value of "-1" for offsets. `"UTF8"` will + * return byte offsets. `"UTF16"` will return + * [code unit](http://unicode.org/glossary/#code_unit) offsets. + * `"UTF32"` will return + * [unicode character](http://unicode.org/glossary/#character) + * offsets. + * } + * @return Annotation + */ + public function analyzeEntitySentiment($content, array $options = []) + { + return new Annotation( + $this->connection->analyzeEntitySentiment( + $this->formatRequest($content, $options) + ) + ); + } + /** * Analyzes the document and provides a full set of text annotations. * diff --git a/tests/snippets/Language/LanguageClientTest.php b/tests/snippets/Language/LanguageClientTest.php index cc59566ef95d..6e7302e17a69 100644 --- a/tests/snippets/Language/LanguageClientTest.php +++ b/tests/snippets/Language/LanguageClientTest.php @@ -84,6 +84,32 @@ public function testAnalyzeSentiment() $this->assertEquals("This is a positive message.", $res->output()); } + public function testAnalyzeEntitySentiment() + { + $this->connection->analyzeEntitySentiment(Argument::any()) + ->shouldBeCalled() + ->willReturn([ + 'entities' => [ + [ + 'name' => 'Google Cloud Platform', + 'sentiment' => [ + 'score' => 1.0 + ] + ] + ] + ]); + + $this->client->___setProperty('connection', $this->connection->reveal()); + + $snippet = $this->snippetFromMethod(LanguageClient::class, 'analyzeEntitySentiment'); + $snippet->addLocal('language', $this->client); + + $res = $snippet->invoke(); + $lines = explode(PHP_EOL, $res->output()); + $this->assertEquals('Entity name: Google Cloud Platform', $lines[0]); + $this->assertEquals("This is a positive message.", $lines[1]); + } + public function testAnalyzeSyntax() { $this->connection->analyzeSyntax(Argument::any()) diff --git a/tests/system/Language/AnalyzeTest.php b/tests/system/Language/AnalyzeTest.php index ba79f471273c..3d57ba21823e 100644 --- a/tests/system/Language/AnalyzeTest.php +++ b/tests/system/Language/AnalyzeTest.php @@ -133,6 +133,76 @@ public function analyzeEntitiesProvider() ]; } + /** + * @dataProvider analyzeEntitySentimentProvider + */ + public function testAnalyzeEntitySentiment($text, $expectedEntities) + { + $result = self::$client->analyzeEntitySentiment($text); + $info = $result->info(); + + foreach ($expectedEntities as $expectedEntity) { + $exists = false; + foreach ($info['entities'] as $entity) { + if ($entity['name'] == $expectedEntity['name']) { + $exists = true; + $this->assertEquals($entity['type'], $expectedEntity['type']); + $this->assertEquals($entity['sentiment'], $expectedEntity['sentiment']); + break; + } + } + $this->assertTrue($exists); + } + } + + public function analyzeEntitySentimentProvider() + { + return [ + [ + 'Do you know the way to San Jose?', + [ + [ + 'name' => 'San Jose', + 'type' => 'LOCATION', + 'sentiment' => [ + 'magnitude' => 0, + 'score' => 0, + ], + ], + [ + 'name' => 'way', + 'type' => 'OTHER', + 'sentiment' => [ + 'magnitude' => 0, + 'score' => 0, + ], + ], + ] + ], + [ + "The road to San Jose is great!", + [ + [ + 'name' => 'San Jose', + 'type' => 'LOCATION', + 'sentiment' => [ + 'magnitude' => 0.3, + 'score' => 0.3, + ], + ], + [ + 'name' => 'road', + 'type' => 'LOCATION', + 'sentiment' => [ + 'magnitude' => 0.3, + 'score' => 0.3, + ], + ], + ] + ] + ]; + } + public function testClassifyText() { $result = self::$client->classifyText( diff --git a/tests/unit/Language/Connection/RestTest.php b/tests/unit/Language/Connection/RestTest.php index 2f770876c836..c0042a2a7e15 100644 --- a/tests/unit/Language/Connection/RestTest.php +++ b/tests/unit/Language/Connection/RestTest.php @@ -77,6 +77,7 @@ public function methodProvider() return [ ['analyzeSentiment'], ['analyzeEntities'], + ['analyzeEntitySentiment'], ['analyzeSyntax'], ['annotateText'], ['classifyText'] diff --git a/tests/unit/Language/LanguageClientTest.php b/tests/unit/Language/LanguageClientTest.php index e42c7264f3b4..e842929cbc74 100644 --- a/tests/unit/Language/LanguageClientTest.php +++ b/tests/unit/Language/LanguageClientTest.php @@ -72,6 +72,22 @@ public function testAnalyzeSentiment($options, $expectedOptions) $this->assertInstanceOf(Annotation::class, $annotation); } + /** + * @dataProvider analyzeDataProvider + */ + public function testAnalyzeEntitySentiment($options, $expectedOptions) + { + $content = $options['content']; + unset($options['content']); + $this->connection + ->analyzeEntitySentiment($expectedOptions) + ->willReturn([]) + ->shouldBeCalledTimes(1); + $this->client->setConnection($this->connection->reveal()); + $annotation = $this->client->analyzeEntitySentiment($content, $options); + $this->assertInstanceOf(Annotation::class, $annotation); + } + /** * @dataProvider analyzeDataProvider */ From bac32ea62be3322bc4b01120bb6106bb2e7e4abe Mon Sep 17 00:00:00 2001 From: Michael Bausor Date: Fri, 10 Nov 2017 14:07:49 -0800 Subject: [PATCH 2/3] Add annotateText support --- src/Language/LanguageClient.php | 7 ++++--- tests/unit/Language/LanguageClientTest.php | 5 +++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/Language/LanguageClient.php b/src/Language/LanguageClient.php index 4438601c7a06..3e26edfba6cb 100644 --- a/src/Language/LanguageClient.php +++ b/src/Language/LanguageClient.php @@ -54,6 +54,7 @@ class LanguageClient 'syntax' => 'extractSyntax', 'entities' => 'extractEntities', 'sentiment' => 'extractDocumentSentiment', + 'entitySentiment' => 'extractEntitySentiment', 'classify' => 'classifyText' ]; @@ -421,9 +422,9 @@ public function classifyText($content, array $options = []) * string represents a Google Cloud Storage URI in the format of * `gs://{bucket-name}/{object-name}`. **Defaults to** `true`. * @type array $features Features to apply to the request. Valid values - * are `syntax`, `sentiment`, `entities`, and `classify`. If no - * features are provided the request will run with all four - * enabled. + * are `syntax`, `sentiment`, `entities`, `entitySentiment`, and + * `classify`. If no features are provided the request will run + * with all features enabled. * @type string $type The document type. Acceptable values are * `PLAIN_TEXT` or `HTML`. **Defaults to** `"PLAIN_TEXT"`. * @type string $language The language of the document. Both ISO diff --git a/tests/unit/Language/LanguageClientTest.php b/tests/unit/Language/LanguageClientTest.php index e842929cbc74..2d542c838aeb 100644 --- a/tests/unit/Language/LanguageClientTest.php +++ b/tests/unit/Language/LanguageClientTest.php @@ -140,11 +140,12 @@ public function testAnnotateText($options, $expectedOptions) { $content = $options['content']; unset($options['content']); - $options['features'] = ['syntax', 'entities', 'sentiment']; + $options['features'] = ['syntax', 'entities', 'sentiment', 'entitySentiment']; $expectedOptions['features'] = [ 'extractSyntax' => true, 'extractEntities' => true, - 'extractDocumentSentiment' => true + 'extractDocumentSentiment' => true, + 'extractEntitySentiment' => true, ]; $this->connection ->annotateText($expectedOptions) From f4256e54a65df2cd78eaeea62e88c8db78766e06 Mon Sep 17 00:00:00 2001 From: Michael Bausor Date: Fri, 10 Nov 2017 14:09:30 -0800 Subject: [PATCH 3/3] Fix phpcs error --- src/Language/Connection/Rest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Language/Connection/Rest.php b/src/Language/Connection/Rest.php index 4b6409a8c8c5..1fad3a489457 100644 --- a/src/Language/Connection/Rest.php +++ b/src/Language/Connection/Rest.php @@ -75,7 +75,7 @@ public function analyzeSentiment(array $args = []) */ public function analyzeEntitySentiment(array $args = []) { - return $this->send('documents', 'analyzeEntitySentiment',$args); + return $this->send('documents', 'analyzeEntitySentiment', $args); } /**