From 7209c80b0f62753cbbe0b29ebaaba61e434d7dce Mon Sep 17 00:00:00 2001 From: Hector Date: Sat, 25 Nov 2017 11:02:49 +0100 Subject: [PATCH] Added new exampled. Added new code to get TailoredAudiences --- examples/analytics.php | 5 +- examples/analytics_async.php | 160 ++++++++++++++++++ examples/tailored_audience_read.php | 30 ++++ ...ience.php => tailored_audience_upload.php} | 0 src/TwitterAds/Account.php | 11 +- src/TwitterAds/Analytics/Job.php | 24 ++- src/TwitterAds/Campaign/LineItem.php | 3 +- src/TwitterAds/Cursor.php | 2 +- src/TwitterAds/Fields/JobFields.php | 3 + src/TwitterAds/Fields/LineItemFields.php | 5 + .../TailoredAudience/TailoredAudienceTest.php | 6 +- 11 files changed, 239 insertions(+), 10 deletions(-) create mode 100644 examples/analytics_async.php create mode 100644 examples/tailored_audience_read.php rename examples/{tailored_audience.php => tailored_audience_upload.php} (100%) diff --git a/examples/analytics.php b/examples/analytics.php index b0033fd..174535a 100644 --- a/examples/analytics.php +++ b/examples/analytics.php @@ -38,7 +38,7 @@ $l = 1; foreach ($campaignsData as $campaign) { echo $i . ": " . $campaign->getId() . " " . $campaign->getName() . " " . $campaign->getStartTime()->format('Y-m-d') . " - " . $campaign->getEntityStatus() . PHP_EOL; - $lineItems = $campaign->getLineItems(); + $lineItems = $campaign->getLineItems([TwitterAds\Fields\LineItemFields::COUNT => 2]); /** @var LineItem $lineItem */ foreach ($lineItems as $lineItem) { echo "\t" . $j . ": " . $lineItem->getId() . " " . $lineItem->getName() . " " . PHP_EOL; @@ -59,6 +59,7 @@ } $l = 1; try { + $async = false; $startDate = new \DateTime($campaign->getStartTime()->format('Y-m-d 00:00:00')); $endDate = new \DateTime('now'); $dates = dateRanges($startDate, $endDate); @@ -74,7 +75,7 @@ AnalyticsFields::END_TIME => $date[1], AnalyticsFields::GRANULARITY => Enumerations::GRANULARITY_TOTAL, AnalyticsFields::PLACEMENT => Enumerations::PLACEMENT_ALL_ON_TWITTER - ], true + ], $async ); $stats = $stats[0]->id_data[0]->metrics; if (!is_null($stats->billed_charge_local_micro)) { diff --git a/examples/analytics_async.php b/examples/analytics_async.php new file mode 100644 index 0000000..1b6a67d --- /dev/null +++ b/examples/analytics_async.php @@ -0,0 +1,160 @@ +getAccounts(); +// load up the account instance, campaign and line item +$account = new Account(ACCOUNT_ID); +$account->read(); +$campaigns = $account->getCampaigns('', [TwitterAds\Fields\CampaignFields::COUNT => 1]); +$campaigns->setUseImplicitFetch(false); +$campaignsData = []; + + +/** @var Campaign $campaign */ +foreach ($campaigns as $campaign) { + $campaignsData[] = $campaign; +} + +$i = 1; +$j = 1; +$l = 1; +foreach ($campaignsData as $campaign) { + echo $i . ": " . $campaign->getId() . " " . $campaign->getName() . " " . $campaign->getStartTime()->format('Y-m-d') . " - " . $campaign->getEntityStatus() . PHP_EOL; + $lineItems = $campaign->getLineItems([TwitterAds\Fields\LineItemFields::COUNT => 2]); + /** @var LineItem $lineItem */ + foreach ($lineItems as $lineItem) { + echo "\t" . $j . ": " . $lineItem->getId() . " " . $lineItem->getName() . " " . PHP_EOL; + echo "\t\tBid: " . ($lineItem->getBidAmountLocalMicro() / 1000000) . PHP_EOL; + echo "\t\tObjective: " . $lineItem->getObjective() . PHP_EOL; + echo "\t\tCharge By: " . $lineItem->getChargeBy() . PHP_EOL; + echo "\t\tBid Unit: " . $lineItem->getBidUnit() . PHP_EOL; + echo "\t\tOptimization: " . $lineItem->getOptimization() . PHP_EOL; + echo "\t\tBid Type: " . $lineItem->getBidType() . PHP_EOL; + $targetingCriterias = $lineItem->getTargetingCriteria(); + /** @var TwitterAds\Campaign\TargetingCriteria $targetingCriteria */ + foreach ($targetingCriterias as $targetingCriteria) { + echo "\t\t" . $l . ": " . $targetingCriteria->getId() . " " . $targetingCriteria->getName() . " " . + + $targetingCriteria->getTargetingType() . " " . $targetingCriteria->getTargetingValue() . PHP_EOL; + + $l++; + } + $l = 1; + try { + $async = true; + $startDate = new \DateTime($campaign->getStartTime()->format('Y-m-d 00:00:00')); + $endDate = new \DateTime('now'); + $dates = dateRanges($startDate, $endDate); + foreach ($dates as $date) { + $job = $lineItem->stats( + [ + TwitterAds\Fields\AnalyticsFields::METRIC_GROUPS_BILLING, + TwitterAds\Fields\AnalyticsFields::METRIC_GROUPS_MOBILE_CONVERSION, + TwitterAds\Fields\AnalyticsFields::METRIC_GROUPS_ENGAGEMENT, + ], + [ + TwitterAds\Fields\AnalyticsFields::START_TIME => $date[0], + AnalyticsFields::END_TIME => $date[1], + AnalyticsFields::GRANULARITY => Enumerations::GRANULARITY_TOTAL, + AnalyticsFields::PLACEMENT => Enumerations::PLACEMENT_ALL_ON_TWITTER + ], $async + ); + while($job->getStatus() == TwitterAds\Fields\JobFields::PROCESSING){ + echo "Job is still processing. Waiting 5 more seconds".PHP_EOL; + $job->read(); + sleep(5); + } + + if($job->getStatus() == TwitterAds\Fields\JobFields::SUCCESS){ + $result = gzfile($job->getUrl()); + $result = implode("", $result); + $stats = json_decode($result)->data; + $stats = $stats[0]->id_data[0]->metrics; + if (!is_null($stats->billed_charge_local_micro)) { + echo "\t\t\t Start: " . $date[0]->format('Y-m-d H:i:s') . PHP_EOL; + echo "\t\t\t End: " . $date[1]->format('Y-m-d H:i:s') . PHP_EOL; + echo "\t\t\t " . ($stats->billed_charge_local_micro[0] / 1000000) . "€" . PHP_EOL; + echo "\t\t\t\t App clicks: "; + getStats($stats->app_clicks); + echo "\t\t\t\t Installs:" . PHP_EOL; + getStats($stats->mobile_conversion_installs); + echo "\t\t\t\t Checkouts:" . PHP_EOL; + getStats($stats->mobile_conversion_checkouts_initiated); + } + } + } + + } catch (\Hborras\TwitterAdsSDK\TwitterAdsException $e) { + print_r($e->getErrors()); + } + + $j++; + } + $j = 1; + $i++; +} + +function getStats($stat) +{ + if ($stat instanceof stdClass) { + foreach (get_object_vars($stat) as $key => $val) { + if (is_array($val)) { + echo "\t\t\t\t\t " . $key . ": " . $val[0] . PHP_EOL; + } else { + echo "\t\t\t\t\t " . $key . " 0" . PHP_EOL; + } + } + } else if (is_array($stat)) { + foreach ($stat as $s) { + echo $s . PHP_EOL; + } + } + +} + +/** + * @param $startTime + * @param $endTime + * @return array + */ +function dateRanges($startTime, $endTime) +{ + $interval = new \DateInterval('P60D'); + $dateRange = new \DatePeriod($startTime, $interval, $endTime); + + $previous = null; + $dates = array(); + foreach ($dateRange as $dt) { + $current = $dt; + if (!empty($previous)) { + $show = $current; + $dates[] = array($previous, $show); + } + $previous = $current; + } + if (isset($dates[count($dates) - 1])) { + $dates[] = array($dates[count($dates) - 1][1], $endTime); + } else { + $dates[] = array($startTime, $endTime); + } + + return $dates; +} \ No newline at end of file diff --git a/examples/tailored_audience_read.php b/examples/tailored_audience_read.php new file mode 100644 index 0000000..640aaa8 --- /dev/null +++ b/examples/tailored_audience_read.php @@ -0,0 +1,30 @@ +read(); + +$tailoredAudiences = $account->getTailoredAudiences(); + +$tailoredAudiences->setDefaultUseImplicitFetch(true); + +foreach ($tailoredAudiences as $tailoredAudience) { + echo $tailoredAudience->getName().PHP_EOL; +} \ No newline at end of file diff --git a/examples/tailored_audience.php b/examples/tailored_audience_upload.php similarity index 100% rename from examples/tailored_audience.php rename to examples/tailored_audience_upload.php diff --git a/src/TwitterAds/Account.php b/src/TwitterAds/Account.php index c758afd..4570144 100644 --- a/src/TwitterAds/Account.php +++ b/src/TwitterAds/Account.php @@ -16,6 +16,7 @@ use Hborras\TwitterAdsSDK\TwitterAds\Campaign\PromotableUser; use Hborras\TwitterAdsSDK\TwitterAds\Creative\Video; use Hborras\TwitterAdsSDK\TwitterAds\Fields\AnalyticsFields; +use Hborras\TwitterAdsSDK\TwitterAds\TailoredAudience\TailoredAudience; use Hborras\TwitterAdsSDK\TwitterAdsException; use Hborras\TwitterAdsSDK\TwitterAds\Fields\AccountFields; @@ -172,9 +173,15 @@ public function getJobs($params = []) } - public function getTailoredAudiences($id = '', $params = []) + /** + * @param array $params + * @return Cursor|Resource + */ + public function getTailoredAudiences($params = []) { - // TODO: Next Release + $tailoredAudienceClass = new TailoredAudience(); + + return $tailoredAudienceClass->loadResource('', $params); } /** diff --git a/src/TwitterAds/Analytics/Job.php b/src/TwitterAds/Analytics/Job.php index 8ab29a2..35f047c 100644 --- a/src/TwitterAds/Analytics/Job.php +++ b/src/TwitterAds/Analytics/Job.php @@ -8,11 +8,12 @@ namespace Hborras\TwitterAdsSDK\TwitterAds\Analytics; use Hborras\TwitterAdsSDK\TwitterAds\Analytics; +use Hborras\TwitterAdsSDK\TwitterAds\Fields\JobFields; class Job extends Analytics { const RESOURCE_COLLECTION = 'stats/jobs/accounts/{account_id}'; - const RESOURCE = 'stats/jobs/accounts/{account_id}/{id}'; + const RESOURCE = 'stats/jobs/accounts/{account_id}'; const ENTITY = 'JOBS'; /** Read Only */ @@ -35,6 +36,27 @@ class Job extends Analytics protected $properties = []; + + public function read($params = []) + { + $resource = str_replace(static::RESOURCE_REPLACE, $this->getTwitterAds()->getAccountId(), static::RESOURCE); + $params[JobFields::JOB_IDS] = $this->id; + $response = $this->getTwitterAds()->get($resource, $params); + if(isset($response->getBody()->data[0])){ + return $this->fromResponse($response->getBody()->data[0]); + } else { + return $this; + } + } + + /** + * @return mixed + */ + public function getId() + { + return $this->id; + } + /** * @return mixed */ diff --git a/src/TwitterAds/Campaign/LineItem.php b/src/TwitterAds/Campaign/LineItem.php index 2a8d717..d8976f5 100644 --- a/src/TwitterAds/Campaign/LineItem.php +++ b/src/TwitterAds/Campaign/LineItem.php @@ -8,6 +8,7 @@ namespace Hborras\TwitterAdsSDK\TwitterAds\Campaign; use Hborras\TwitterAdsSDK\TwitterAds\Analytics; +use Hborras\TwitterAdsSDK\TwitterAds\Analytics\Job; use Hborras\TwitterAdsSDK\TwitterAds\Creative\PromotedTweet; use Hborras\TwitterAdsSDK\TwitterAds\Cursor; use Hborras\TwitterAdsSDK\TwitterAds\Fields\AnalyticsFields; @@ -82,7 +83,7 @@ public function getPromotedTweets($params = []) * @param $metricGroups * @param array $params * @param bool $async - * @return mixed + * @return Job| mixed */ public function stats($metricGroups, $params = [], $async = false) { diff --git a/src/TwitterAds/Cursor.php b/src/TwitterAds/Cursor.php index 056c9fa..f82d3e9 100644 --- a/src/TwitterAds/Cursor.php +++ b/src/TwitterAds/Cursor.php @@ -80,7 +80,7 @@ public function fetched() */ public function next() { - if ($this->current_index == $this->getIndexRight()) { + if ($this->current_index == $this->getIndexRight() && !is_null($this->next_cursor)) { if ($this->getUseImplicitFetch()) { $this->fetchNext(); if ($this->current_index == $this->getIndexRight()) { diff --git a/src/TwitterAds/Fields/JobFields.php b/src/TwitterAds/Fields/JobFields.php index b20220c..10bc768 100644 --- a/src/TwitterAds/Fields/JobFields.php +++ b/src/TwitterAds/Fields/JobFields.php @@ -23,4 +23,7 @@ class JobFields const UPDATED_AT = 'updated_at'; const METRIC_GROUPS = 'metric_groups'; const JOB_IDS = 'job_ids'; + const PROCESSING = 'PROCESSING'; + const SUCCESS = 'SUCCESS'; + const CANCELLED = 'CANCELLED'; } \ No newline at end of file diff --git a/src/TwitterAds/Fields/LineItemFields.php b/src/TwitterAds/Fields/LineItemFields.php index 473746a..3df16a6 100644 --- a/src/TwitterAds/Fields/LineItemFields.php +++ b/src/TwitterAds/Fields/LineItemFields.php @@ -34,4 +34,9 @@ class LineItemFields const ADVERTISER_DOMAIN = 'advertiser_domain'; const ADVERTISER_USER_ID = 'advertiser_user_id'; const LINE_ITEM_IDS = 'line_item_ids'; + const WITH_DELETED = 'with_deleted'; + const COUNT = 'count'; + const SORT_BY = 'sort_by'; + const DRAFT_ONLY = 'draft_only'; + const ENTITY_STATUS = 'entity_status'; } \ No newline at end of file diff --git a/tests/TwitterAds/TailoredAudience/TailoredAudienceTest.php b/tests/TwitterAds/TailoredAudience/TailoredAudienceTest.php index 0828644..737c0e6 100644 --- a/tests/TwitterAds/TailoredAudience/TailoredAudienceTest.php +++ b/tests/TwitterAds/TailoredAudience/TailoredAudienceTest.php @@ -20,12 +20,12 @@ public function testTailoredAudiencesWillThrowAnExceptionWithAnInvalidType() public function testTailoredAudiencesCanBeAddedFetchedAndDeletedSuccessfully() { - $audience = new TailoredAudience($this->account); + $audience = new TailoredAudience(); $audience->setListType(TailoredAudience::LIST_TYPE_EMAIL); $audience->setName('test audience'); $newAudience = $audience->save(); - $fetched = (new TailoredAudience($this->account))->load($newAudience->getId()); + $fetched = (new TailoredAudience())->load($newAudience->getId()); $this->assertEquals($fetched->getId(), $newAudience->getId()); $this->assertEquals($fetched->getName(), $newAudience->getName()); $this->assertEquals($fetched->getListType(), $newAudience->getListType()); @@ -35,7 +35,7 @@ public function testTailoredAudiencesCanBeAddedFetchedAndDeletedSuccessfully() public function testTailoredAudiencesCanBeFetched() { - $audience = new TailoredAudience($this->account); + $audience = new TailoredAudience(); $result = iterator_to_array($audience->all()); $this->assertGreaterThan(0, $result);