diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..2d24543
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+vendor/
+composer.lock
+.DS_Store
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..192b1c3
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+DON'T BE A DICK PUBLIC LICENSE
+
+Version 1, December 2009
+
+Copyright (C) 2009 Philip Sturgeon email@philsturgeon.co.uk
+
+Everyone is permitted to copy and distribute verbatim or modified copies of this license document, and changing it is allowed as long as the name is changed.
+
+DON'T BE A DICK PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+Do whatever you like with the original work, just don't be a dick.
+
+Being a dick includes - but is not limited to - the following instances:
+
+1a. Outright copyright infringement - Don't just copy this and change the name.
+1b. Selling the unmodified original with no work done what-so-ever, that's REALLY being a dick.
+1c. Modifying the original work to contain hidden harmful content. That would make you a PROPER dick.
+
+If you become rich through modifications, related works/services, or supporting the original work, share the love. Only a dick would make loads off this work and not buy the original works creator(s) a pint.
+
+Code is provided with no warranty. Using somebody else's code and bitching when it goes wrong makes you a DONKEY dick. Fix the problem yourself. A non-dick would submit the fix back.
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..409316a
--- /dev/null
+++ b/README.md
@@ -0,0 +1,15 @@
+Composer Library Template
+=========================
+
+If you are trying to create a new PHP Composer library, whether it will be going to submitted to packagist.org or just in your Github account, this template of files will surely help you make the process a lot easier and faster.
+
+Features
+--------
+
+* PSR-4 autoloading compliant structure
+* Unit-Testing with PHPUnit
+* Comprehensive Guides and tutorial
+* Easy to use to any framework or even a plain php file
+
+
+I encourage that you put more information on this readme file instead of leaving it as is. See [http://www.darwinbiler.com/designing-and-making-the-readme-file-for-your-github-repository/](How to make a README file) for more info.
diff --git a/composer.json b/composer.json
new file mode 100644
index 0000000..4d21c76
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,24 @@
+{
+ "name": "lvengine/analytics",
+ "description": "Fetch data from GA",
+ "license": "proprietary",
+ "authors": [
+ {
+ "name": "João Serpa | LVEngine",
+ "email": "joaoserpa@lvengine.com"
+ }
+ ],
+ "type": "project",
+ "require": {
+ "php": ">=5.4",
+ "google/apiclient": "^2.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "5.2.*"
+ },
+ "autoload": {
+ "psr-4": {
+ "Analytics\\": "src/Analytics/"
+ }
+ }
+}
diff --git a/index.php b/index.php
new file mode 100644
index 0000000..8d5857f
--- /dev/null
+++ b/index.php
@@ -0,0 +1,17 @@
+setViewId("137104990");
+$audience->setDate("2017-08-01", "2017-08-07");
+
+echo "
";
+print_r($audience->internalSearches());
+echo "
";
diff --git a/phpunit.xml b/phpunit.xml
new file mode 100644
index 0000000..4bfdb04
--- /dev/null
+++ b/phpunit.xml
@@ -0,0 +1,12 @@
+
+
+
+ tests
+
+
+
\ No newline at end of file
diff --git a/src/Analytics/aquisition.php b/src/Analytics/aquisition.php
new file mode 100644
index 0000000..9f538cc
--- /dev/null
+++ b/src/Analytics/aquisition.php
@@ -0,0 +1,56 @@
+metricsByDimensions(
+ array(
+ 'metrics' => array('sessions'),
+ 'dimensions' => array('channelGrouping')
+ )
+ );
+ }
+ public function sessionsBySourcesMediums()
+ {
+ return $this->metricsByDimensions(
+ array(
+ 'metrics' => array('sessions'),
+ 'dimensions' => array('sourceMedium')
+ )
+ );
+ }
+ public function campaigns()
+ {
+ return $this->metricsByDimensions(
+ array(
+ 'metrics' => array('users', 'newUsers', 'sessions', 'bounceRate', 'avgSessionDuration'),
+ 'dimensions' => array('campaign'),
+ "sorts" => array(
+ array(
+ 'fieldName' => 'ga:users',
+ 'orderType' => 'VALUE',
+ 'sortOrder' => 'DESCENDING'
+ )
+ ),
+ 'page_size' => 21
+ )
+ );
+ }
+ // ────────────────────────────────────────────────────────────────────────────────
+
+}
\ No newline at end of file
diff --git a/src/Analytics/audience.php b/src/Analytics/audience.php
new file mode 100644
index 0000000..4444ae5
--- /dev/null
+++ b/src/Analytics/audience.php
@@ -0,0 +1,65 @@
+metricsByDimensions(
+ array(
+ 'metrics' => array('sessions'),
+ 'dimensions' => array('userGender')
+ )
+ );
+ }
+ public function sessionsByAge()
+ {
+ return $this->metricsByDimensions(
+ array(
+ 'metrics' => array('sessions'),
+ 'dimensions' => array('userAgeBracket')
+ )
+ );
+ }
+ public function sessionsByCountry()
+ {
+ return $this->metricsByDimensions(
+ array(
+ 'metrics' => array('sessions'),
+ 'dimensions' => array('country')
+ )
+ );
+ }
+ public function sessionsAndUsers()
+ {
+ return $this->metricsByDimensions(
+ array(
+ 'metrics' => array('sessions', 'users'),
+ 'dimensions' => array('date')
+ )
+ );
+ }
+ public function bounceRate()
+ {
+ return $this->metricsByDimensions(
+ array(
+ 'metrics' => array('bounceRate'),
+ )
+ );
+ }
+ // ────────────────────────────────────────────────────────────────────────────────
+
+}
diff --git a/src/Analytics/behavior.php b/src/Analytics/behavior.php
new file mode 100644
index 0000000..cfd773e
--- /dev/null
+++ b/src/Analytics/behavior.php
@@ -0,0 +1,72 @@
+metricsByDimensions(
+ array(
+ 'metrics' => array('searchUniques'),
+ 'dimensions' => array('searchKeyword'),
+ 'sorts' => array(
+ array(
+ 'fieldName' => 'ga:searchUniques',
+ 'orderType' => 'VALUE',
+ 'sortOrder' => 'DESCENDING'
+ )
+ ),
+ "page_size" => 25
+ )
+ );
+ }
+ public function internalSearchesWithoutResults()
+ {
+ return $this->metricsByDimensions(
+ array(
+ 'metrics' => array('totalEvents', 'uniqueEvents'),
+ 'dimensions' => array('eventLabel'),
+ 'sorts' => array(
+ array(
+ 'fieldName' => 'ga:totalEvents',
+ 'orderType' => 'VALUE',
+ 'sortOrder' => 'DESCENDING'
+ )
+ ),
+ 'page_size' => 25,
+ 'filters' => 'ga:eventAction==Sem Resultados'
+ )
+ );
+ }
+ public function eCommerceEvents()
+ {
+ return $this->metricsByDimensions(
+ array(
+ 'metrics' => array('totalEvents', 'uniqueEvents'),
+ 'dimensions' => array('eventAction'),
+ 'sorts' => array(
+ array(
+ 'fieldName' => 'ga:totalEvents',
+ 'orderType' => 'VALUE',
+ 'sortOrder' => 'DESCENDING'
+ )
+ ),
+ 'page_size' => 25,
+ 'filters' => 'ga:eventCategory==eCommerce,ga:eventAction!=Product Impression'
+ )
+ );
+ }
+ // ────────────────────────────────────────────────────────────────────────────────
+}
\ No newline at end of file
diff --git a/src/Analytics/conversion.php b/src/Analytics/conversion.php
new file mode 100644
index 0000000..4cc1291
--- /dev/null
+++ b/src/Analytics/conversion.php
@@ -0,0 +1,121 @@
+metricsByDimensions(
+ array(
+ 'metrics' => array('totalValue'),
+ 'dimensions' => array('date')
+ )
+ );
+ }
+ public function refundByDay()
+ {
+ return $this->metricsByDimensions(
+ array(
+ 'metrics' => array('refundAmount'),
+ 'dimensions' => array('date')
+ )
+ );
+ }
+ public function campaignsRevenue()
+ {
+ return $this->metricsByDimensions(
+ array(
+ 'metrics' => array('transactionRevenue'),
+ 'dimensions' => array('campaign'),
+ 'sorts' => array(
+ array(
+ 'fieldName' => 'ga:transactionRevenue',
+ 'orderType' => 'VALUE',
+ 'sortOrder' => 'DESCENDING'
+ )
+ )
+ )
+ );
+ }
+ public function topProducts()
+ {
+ return $this->metricsByDimensions(
+ array(
+ 'metrics' => array('itemRevenue','itemQuantity'),
+ 'dimensions' => array('productName'),
+ 'sorts' => array(
+ array(
+ 'fieldName' => 'ga:itemRevenue',
+ 'orderType' => 'VALUE',
+ 'sortOrder' => 'DESCENDING'
+ ),
+ array(
+ 'fieldName' => 'ga:itemQuantity',
+ 'orderType' => 'VALUE',
+ 'sortOrder' => 'DESCENDING'
+ )
+ ),
+ "filters" => "ga:itemRevenue!=0"
+ )
+ );
+ }
+ public function topCategories()
+ {
+ return $this->metricsByDimensions(
+ array(
+ 'metrics' => array('itemRevenue','itemQuantity'),
+ 'dimensions' => array('productCategoryHierarchy'),
+ 'sorts' => array(
+ array(
+ 'fieldName' => 'ga:itemRevenue',
+ 'orderType' => 'VALUE',
+ 'sortOrder' => 'DESCENDING'
+ ),
+ array(
+ 'fieldName' => 'ga:itemQuantity',
+ 'orderType' => 'VALUE',
+ 'sortOrder' => 'DESCENDING'
+ )
+ ),
+ "filters" => "ga:itemRevenue!=0"
+ )
+ );
+ }
+ public function topBrands()
+ {
+ return $this->metricsByDimensions(
+ array(
+ 'metrics' => array('itemRevenue','itemQuantity'),
+ 'dimensions' => array('productBrand'),
+ 'sorts' => array(
+ array(
+ 'fieldName' => 'ga:itemRevenue',
+ 'orderType' => 'VALUE',
+ 'sortOrder' => 'DESCENDING'
+ ),
+ array(
+ 'fieldName' => 'ga:itemQuantity',
+ 'orderType' => 'VALUE',
+ 'sortOrder' => 'DESCENDING'
+ )
+ ),
+ "filters" => "ga:itemRevenue!=0"
+ )
+ );
+ }
+ // ────────────────────────────────────────────────────────────────────────────────
+
+}
\ No newline at end of file
diff --git a/src/Analytics/credentials.json b/src/Analytics/credentials.json
new file mode 100644
index 0000000..cbad99f
--- /dev/null
+++ b/src/Analytics/credentials.json
@@ -0,0 +1,12 @@
+{
+ "type": "service_account",
+ "project_id": "e-stat-174216",
+ "private_key_id": "2143cbb1525bc7d9b788474cfec5c116f21dd95c",
+ "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCIilZPtPcvaIwu\nGTcbvbxEPZgt9vJJqXIYR0tihLfKzd7vmwHvBh8RRRRltU4I0si159yy2PCZbXRy\nb6l4zZnyZ35D3X5r5T6YV3K/hQQxGby8VmnSJP2Sz/JkcOpZMp59V+H7QaGuqyGm\nCxEZWtU5oJ8Gx66ExpokRAgHxioIcggOjSgOUCt1P0x9NZo9Xs/TNQseWa+4gqpA\nWRuDjUwTzTcuj+OTetAlWR7s74TRKBA3CX9dmqu3TSSDDCSarjBshWxhelz3UGYj\n52xcvNux8ZbB8fYnZ2FBFOqMV3D0nc3uVWVvLM7YNL0pS9bA6Wd413xQuHFz3UVQ\nQYhLxYMXAgMBAAECggEAAdOpVEytXUwun/PvaabFYjuuvGKy8CsHtJfI7usBUyx4\n9fINeby2ZV1BaMZJt9LWI5+UCNff3uBOMApwFTEvBPAUijo9lZpOFuyzQ35h8CQ8\n2F+RmoxV0NqJDttMj1/0Kzol8wjNmHrVVZWNUi5bGaJyrj0KsoppB+DZzfzSlXqo\nFxPU+9IovoqUqVM3vCdrOXX36fkDFtGcmohRgKOzk4u/ARxVudz7QgbgU9gsd8hI\nAb+AYD9qt7qnyazVs29X94my9SlVtQK/s0eNkvwrfWJUkyeE1eWcCZLlCSdPOBUP\nGv1qt2ArBwHYxldkOKzh0CJoteUbZIvWS2zBaXHlJQKBgQC9qOn6zxWE0EhZEzhq\nZpf2yY9qutj4LzS10GsaojIqC9jnnyGZIO14o/pAGkGNeu4egrqncxNnlIW0Kpmj\nN/8UzGw13rtW3+90ZgEawBVx+pibf19gbwgk3TdQVfwFCxr3HaRBHHwX7rQgOsok\n7EFu7hOiJHERKWI7bQlV23FAnQKBgQC4TNf0dwAYD5S+mMlYs77ORTL4uUNjKSR4\ndU4YvGmFnUt+qACcPFVADH+1sIUZEiz2/+xRyQN02bqWcnHPy5T1Hw1wQxxkV5L0\nKqEeUC/D9vMyZW82RiJuHZ7ZBKv9ril+SdlGWSWsNFRY8oum0GR7oIxs17Zh/3op\nGXXyDUPiQwKBgB5wO40LKzLzkojpMsawzHbJBoFkl2nNebIsTuQpX8+rsxYJTgUb\nacFQ39rl29tu/URcSsSRDW40QfkWVS4C0Kdv33YN1xcsPWv66vZ2GXr/cvqRyKbb\nav0vm68C/b15eMxsL25bufbFUpdRmBuw5xd8kh4VpyfP8noDF9p1q4lpAoGAJLrD\nyyewMBti1H1Um0XvP+KQnvslD+0SJKOUNd/O098ePZaz0G9BuisDhK0ySWXS6kLk\n0QPTmYUO547VWclD3XobzoTBcsn1Mo4QYB8w9cgQfbmzaUie8f0bPDrvH/aGtHF5\nSMjZdjFTogpshIlBjVXYxpRS98LXkLtPQzcbkUsCgYAc/945De1IJeAzvctHVRPM\nX+6XolGpj3ocJrE9lLazLr1bGD7H5PN45lCkha/srZHoeJt1GpOSiTq+3IXpnqTH\n0HRCxK06VhUhpMo+tWdg4qyfdzKgAU1ng0SxmypFDks6vnfgfP1XXGQcI2BmPOmI\nBfCDPcmlV3OamW4AMlvOqA==\n-----END PRIVATE KEY-----\n",
+ "client_email": "e-stat@e-stat-174216.iam.gserviceaccount.com",
+ "client_id": "103223646722037248635",
+ "auth_uri": "https://accounts.google.com/o/oauth2/auth",
+ "token_uri": "https://accounts.google.com/o/oauth2/token",
+ "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
+ "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/e-stat%40e-stat-174216.iam.gserviceaccount.com"
+}
diff --git a/src/Analytics/ga.php b/src/Analytics/ga.php
new file mode 100644
index 0000000..cbbebac
--- /dev/null
+++ b/src/Analytics/ga.php
@@ -0,0 +1,489 @@
+config['app_name'] = "LVEngine - Google Analytics";
+
+ /**
+ * Config Google_Client
+ */
+ $this->googleClientConfig();
+ }
+
+
+ //
+ // ─── CONFIGURATION Methods ──────────────────────────────────────────────────────────────
+ //
+ /**
+ * Method to set default Google Configuration.
+ *
+ * @return void
+ */
+ private function googleClientConfig()
+ {
+ /**
+ * Qual o melhor local para o ficheiro?
+ */
+ $KEY_FILE_LOCATION = __DIR__ . '/credentials.json';
+ $this->client = new Google_Client();
+ $this->client->setApplicationName($this->config['app_name']);
+ $this->client->setAuthConfig($KEY_FILE_LOCATION);
+ //$this->client->useApplicationDefaultCredentials();
+ $this->client->addScope("https://www.googleapis.com/auth/analytics.readonly");
+ $this->analytics = new Google_Service_AnalyticsReporting($this->client);
+ }
+
+ /**
+ * Set the View ID.
+ *
+ * @param [string] $view_id
+ * @return void
+ */
+ public function setViewId( $view_id )
+ {
+ $this->config['view_id'] = $view_id;
+ }
+ // ────────────────────────────────────────────────────────────────────────────────
+
+
+ //
+ // ─── METHODS TO HANDLE THE QUERIES ──────────────────────────────────────────────
+ //
+
+ //
+ // ─── PRIVATE METHODS ─────────────────────────────────────────────
+ //
+ /**
+ * Validate the Request by checking the required fields.
+ *
+ * @return void
+ */
+ private function validateRequest()
+ {
+ /**
+ * View ID.
+ */
+ if ( !isset($this->config['view_id']) || empty($this->config['view_id']) )
+ throw new Exception('No VIEW ID set. Use the method ->setViewId([string] $view_id).');
+ /**
+ * Dates.
+ */
+ if (!$this->date_range)
+ throw new Exception('No date range selected. Use the method ->setDate($begin, $end).');
+ else {
+ if (!$this->date_range->getStartDate())
+ throw new Exception('No start date selected. Use the method ->setDate($begin, $end).');
+ if (!$this->date_range->getEndDate())
+ throw new Exception('No end date selected. Use the method ->setDate($begin, $end).');
+ }
+ }
+
+ /**
+ * Method to set the sorts.
+ *
+ * @param array $sorts
+ * @return void
+ */
+ private function setSorts( array $sorts )
+ {
+ /**
+ * Create the sorts array to be inserted in Request.
+ */
+ $this->sorts = array();
+
+ /**
+ * Iterate all sorts and add to array.
+ */
+ foreach ($sorts as $sort) {
+ $new_sort = new Google_Service_AnalyticsReporting_OrderBy();
+ $new_sort->setFieldName( $sort['fieldName'] );
+ $new_sort->setOrderType( $sort['orderType'] );
+ $new_sort->setSortOrder( $sort['sortOrder'] );
+ $this->sorts[] = $new_sort;
+ }
+ }
+
+ /**
+ * Method to limit the returned results.
+ *
+ * @param [int] $limit
+ * @return void
+ */
+ private function setPageSize($limit)
+ {
+ $this->page_size = $limit;
+ }
+
+ /**
+ * Methdo to set filters.
+ *
+ * @param [string] $filters
+ * @return void
+ */
+ private function setFilters($filters)
+ {
+ $this->filters = $filters;
+ }
+
+ /**
+ * Method to set metrics for Request.
+ *
+ * @param array $metrics
+ * @return void
+ */
+ private function setMetrics( array $metrics )
+ {
+ /**
+ * Create the metrics array to be inserted in Request.
+ */
+ $this->metrics = array();
+
+ /**
+ * Iterate all metrics passed and add to array.
+ */
+ foreach ($metrics as $metric) {
+ $new_metric = new Google_Service_AnalyticsReporting_Metric();
+ $new_metric->setExpression('ga:' . $metric);
+ $this->metrics[] = $new_metric;
+ }
+ }
+
+ /**
+ * Method to set dimensions for Request.
+ *
+ * @param array $dimensions
+ * @return void
+ */
+ private function setDimensions( array $dimensions )
+ {
+ /**
+ * Create the dimensions array to be inserted in Request.
+ */
+ $this->dimensions = array();
+
+ /**
+ * Iterate all dimensions and add to array.
+ */
+ foreach ($dimensions as $dimension) {
+ $new_dimension = new Google_Service_AnalyticsReporting_Dimension();
+ $new_dimension->setName('ga:' . $dimension);
+ $this->dimensions[] = $new_dimension;
+ }
+ }
+
+ /**
+ * Method to set and config the Request.
+ *
+ * @return void
+ */
+ private function setRequest()
+ {
+ // Create the ReportRequest object.
+ $this->request = new Google_Service_AnalyticsReporting_ReportRequest();
+ $this->request->setViewId( $this->config['view_id'] );
+ $this->request->setDateRanges( $this->date_range );
+ $this->request->setMetrics( $this->metrics );
+ $this->request->setDimensions( $this->dimensions );
+ $this->request->setOrderBys( $this->sorts );
+ $this->request->setPageSize( $this->page_size );
+ $this->request->setFiltersExpression( $this->filters );
+ }
+
+ /**
+ * Method to set and config report.
+ *
+ * @return void
+ */
+ private function setReport()
+ {
+ /**
+ * Sets and configs the Request.
+ */
+ $this->setRequest();
+
+ /**
+ * Create and set Report.
+ */
+ $this->report = new Google_Service_AnalyticsReporting_GetReportsRequest();
+ $this->report->setReportRequests( array( $this->request ) );
+
+ $report = $this->analytics->reports->batchGet( $this->report );
+ return $this->getData( $report );
+ }
+ // ─────────────────────────────────────────────────────────────────
+
+ //
+ // ─── PUBLIC METHODS ──────────────────────────────────────────────
+ //
+ /**
+ * Method to set the date range for report.
+ *
+ * @param [date] $begin
+ * @param [date] $end
+ * @return void
+ */
+ public function setDate( $begin, $end )
+ {
+ /**
+ * Create date object.
+ */
+ $this->date_range = new Google_Service_AnalyticsReporting_DateRange();
+ /**
+ * Set the date ranges.
+ */
+ $this->date_range->setStartDate( $begin );
+ $this->date_range->setEndDate( $end );
+ }
+ // ─────────────────────────────────────────────────────────────────
+
+ // ────────────────────────────────────────────────────────────────────────────────
+
+
+
+ //
+ // ─── METHODS TO HANDLE RESULTS ──────────────────────────────────────────────────
+ //
+ /**
+ * Method to extract Dimensions from Report.
+ *
+ * @param [Report] $report
+ * @return void
+ */
+ private function getDimensions( $report )
+ {
+ /**
+ * Prevent dimensions error.
+ */
+ $dimensions = $report->getColumnHeader()->getDimensions();
+ if ( !$dimensions ) return null;
+
+ /**
+ * Only executes if there are dimensions.
+ */
+ $ret_dimensions = array();
+ foreach ($dimensions as $dimension) {
+ $ret_dimensions[] = explode("ga:", $dimension)[1];
+ }
+ return $ret_dimensions;
+ }
+
+ /**
+ * Method to extract Metrics Headers from Report.
+ *
+ * @param [Report] $reports
+ * @return void
+ */
+ private function getMetrics( $report )
+ {
+ $metrics = array();
+ foreach ($report->getColumnHeader()->getMetricHeader()->getMetricHeaderEntries() as $metric) {
+ $metrics[] = explode('ga:', $metric->getName())[1];
+ }
+ return $metrics;
+ }
+
+ private function getData( $reports )
+ {
+ $data = array(
+ "rows" => array()
+ );
+ foreach ($reports as $report) {
+ /**
+ * Get headers.
+ */
+ $dimensionHeaders = $this->getDimensions( $report );
+ if ( $dimensionHeaders ) // Dimensions are not required.
+ $data['dimensions'] = $dimensionHeaders;
+
+ $metricHeaders = $this->getMetrics( $report ); // Metrics are required.
+
+ /**
+ * Get Rows and iterate.
+ */
+ $rows = $report->getData()->getRows();
+ foreach ($rows as $row) {
+
+ /**
+ * Handle Metrics.
+ */
+ $metrics = $row->getMetrics();
+ $ret_metrics = array();
+ foreach ($metrics as $metric) {
+ $i = 0; // Counter.
+ foreach ($metric->getValues() as $value) {
+ $ret_metrics[] = array(
+ "label" => $metricHeaders[$i],
+ "value" => $value
+ );
+ $i++; // Increase counter.
+ }
+ }
+
+ /**
+ * Only add the dimensions if they exist.
+ */
+ if ( $dimensionHeaders ) {
+ $data['rows'][] = array(
+ "dimensions" => $row->getDimensions(),
+ "metrics" => $ret_metrics
+ );
+ } else {
+ $data['rows'] = $ret_metrics;
+ }
+ }
+
+ }
+ return $data;
+ }
+ // ────────────────────────────────────────────────────────────────────────────────
+
+
+
+ //
+ // ─── API Generic METHODS ────────────────────────────────────────────────────────────────
+ //
+ /**
+ * Generic Method to build the Requests.
+ * ----
+ * $req = array(
+ * "metrics" => array(),
+ * "dimensions" => array(),
+ * "sorts" => array(),
+ * "page_size" => int,
+ * "filters" => string, // comma separated conditions
+ * )
+ *
+ * @return [array] $data
+ */
+ protected function metricsByDimensions(array $req)
+ {
+ try {
+ /**
+ * Checks necessary fields.
+ */
+ $this->validateRequest();
+
+ /**
+ * Add metrics to request.
+ */
+ $this->setMetrics( $req['metrics'] );
+
+ /**
+ * Add dimensions to request.
+ */
+ if ( $req['dimensions'] )
+ $this->setDimensions( $req['dimensions'] );
+
+ /**
+ * Add Sorts/PageSize/Filters to request.
+ */
+ if ( $req['sorts'] )
+ $this->setSorts( $req['sorts'] );
+
+ if ( $req['page_size'] )
+ $this->setPageSize( $req['page_size'] );
+
+ if ( $req['filters'] )
+ $this->setFilters( $req['filters'] );
+
+ /**
+ * Make the report.
+ * ---
+ * Also formats data.
+ */
+ $data = $this->setReport();
+
+ /**
+ * Return $data.
+ */
+ return $data;
+
+ } catch (Exception $e) {
+ return $e->getMessage();
+ }
+ }
+ // ─────────────────────────────────────────────────────────────────
+
+
+}
+
diff --git a/tests/YourClassTest.php b/tests/YourClassTest.php
new file mode 100644
index 0000000..cf03578
--- /dev/null
+++ b/tests/YourClassTest.php
@@ -0,0 +1,39 @@
+assertTrue(is_object($var));
+ unset($var);
+ }
+
+ /**
+ * Just check if the YourClass has no syntax error
+ *
+ * This is just a simple check to make sure your library has no syntax error. This helps you troubleshoot
+ * any typo before you even use this library in a real project.
+ *
+ */
+ public function testMethod1(){
+ $var = new Buonzz\Template\YourClass;
+ $this->assertTrue($var->method1("hey") == 'Hello World');
+ unset($var);
+ }
+
+}
\ No newline at end of file