Commit cebc9837 authored by Guy Thouret's avatar Guy Thouret
Browse files

Extract record view details from analytics/views api call - #1077

parent e5c6b2d3
Loading
Loading
Loading
Loading
+28 −109
Original line number Diff line number Diff line
@@ -4,10 +4,7 @@
namespace Minds\Controllers\api\v2\analytics;

use Minds\Api\Factory;
use Minds\Core;
use Minds\Core\Di\Di;
use Minds\Entities;
use Minds\Helpers\Counters;
use Minds\Core\Analytics;
use Minds\Interfaces;

class views implements Interfaces\Api
@@ -19,120 +16,42 @@ class views implements Interfaces\Api

    public function post($pages)
    {
        $viewsManager = new Core\Analytics\Views\Manager();
        $type = $pages[0];
        $identifier = $pages[1] ?? '';
        $clientMeta = $_POST['client_meta'] ?? [];

        switch ($pages[0]) {
            case 'boost':
                $expire = Di::_()->get('Boost\Network\Expire');
                $metrics = Di::_()->get('Boost\Network\Metrics');
                $manager = Di::_()->get('Boost\Network\Manager');
        $recordView = new Analytics\Views\Record();
        $recordView->setClientMeta($clientMeta)->setIdentifier($identifier);

                $urn = "urn:boost:newsfeed:{$pages[1]}";
        $response = ['status' => 'success'];

                $boost = $manager->get($urn, [ 'hydrate' => true ]);
                if (!$boost) {
                    return Factory::response([
                        'status' => 'error',
                        'message' => 'Could not find boost'
                    ]);
        if ($type == Analytics\Views\View::TYPE_BOOST) {
            $success = $recordView->recordBoost();
            if ($success) {
                $response = array_merge($response, $recordView->getBoostImpressionsData());
            } else {
                $response['status'] = 'error';
                $response['message'] = $recordView->getLastError();
            }
        } elseif ($type == Analytics\Views\View::TYPE_ACTIVITY || $type === Analytics\Views\View::TYPE_ENTITY) {
            $success = $recordView->recordEntity();

                $count = $metrics->incrementViews($boost);

                if ($count > $boost->getImpressions()) {
                    $expire->setBoost($boost);
                    $expire->expire();
                }

                Counters::increment($boost->getEntity()->guid, "impression");
                Counters::increment($boost->getEntity()->owner_guid, "impression");

                try {
                    // TODO: Ensure client_meta campaign matches this boost

                    $viewsManager->record(
                        (new Core\Analytics\Views\View())
                            ->setEntityUrn($boost->getEntity()->getUrn())
                            ->setOwnerGuid((string) $boost->getEntity()->getOwnerGuid())
                            ->setClientMeta($_POST['client_meta'] ?? [])
                    );
                } catch (\Exception $e) {
                    error_log($e);
                }

                return Factory::response([
                    'status' => 'success',
                    'impressions' => $boost->getImpressions(),
                    'impressions_met' => $count,
                ]);
                break;
            case 'activity':
            case 'entity':
                $entity = Entities\Factory::build($pages[1]);

                if (!$entity) {
                    return Factory::response([
                        'status' => 'error',
                        'message' => 'Could not the entity'
                    ]);
                }

                if ($entity->type === 'activity') {
                    try {
                        Core\Analytics\App::_()
                        ->setMetric('impression')
                        ->setKey($entity->guid)
                        ->increment();

                        if ($entity->remind_object) {
                            Core\Analytics\App::_()
                            ->setMetric('impression')
                            ->setKey($entity->remind_object['guid'])
                            ->increment();

                            Core\Analytics\App::_()
                            ->setMetric('impression')
                            ->setKey($entity->remind_object['owner_guid'])
                            ->increment();
                        }

                        Core\Analytics\User::_()
                        ->setMetric('impression')
                        ->setKey($entity->owner_guid)
                        ->increment();
                    } catch (\Exception $e) {
                        error_log($e->getMessage());
            if (!$success) {
                $response['status'] = 'error';
                $response['message'] = $recordView->getLastError();
            }
        }

                try {
                    $viewsManager->record(
                        (new Core\Analytics\Views\View())
                            ->setEntityUrn($entity->getUrn())
                            ->setOwnerGuid((string) $entity->getOwnerGuid())
                            ->setClientMeta($_POST['client_meta'] ?? [])
                    );
                } catch (\Exception $e) {
                    error_log($e);
                }

                Di::_()->get('Referrals\Cookie')
                    ->setEntity($entity)
                    ->create();

                break;
        }

        return Factory::response([]);
        Factory::response($response);
    }

    public function put($pages)
    {
        return Factory::response([]);
        Factory::response([]);
    }

    public function delete($pages)
    {
        return Factory::response([]);
        Factory::response([]);
    }
}
+145 −0
Original line number Diff line number Diff line
<?php

namespace Minds\Core\Analytics\Views;

use Minds\Core;
use Minds\Core\Di\Di;
use Minds\Entities;
use Minds\Helpers\Counters;

class Record
{
    /** @var Manager */
    protected $manager;
    /** @var string $lastError */
    protected $lastError = '';
    /** @var array $boostData */
    protected $boostData;
    /** @var string $identifier **/
    protected $identifier = '';
    /** @var array $clientMeta */
    protected $clientMeta;

    public function __construct(Manager $manager=null)
    {
        $this->manager = $manager ?: new Manager();
    }

    public function setClientMeta(array $clientMeta): self
    {
        $this->clientMeta = $clientMeta;
        return $this;
    }

    public function setIdentifier(string $identifier): self
    {
        $this->identifier = $identifier;
        return $this;
    }

    public function getBoostImpressionsData(): array
    {
        return $this->boostData;
    }

    public function getLastError(): string
    {
        return $this->lastError;
    }

    public function recordBoost(): bool
    {
        $expire = Di::_()->get('Boost\Network\Expire');
        $metrics = Di::_()->get('Boost\Network\Metrics');
        $manager = Di::_()->get('Boost\Network\Manager');

        $urn = "urn:boost:newsfeed:{$this->identifier}";

        $boost = $manager->get($urn, [ 'hydrate' => true ]);
        if (!$boost) {
            $this->lastError = 'Could not find boost';
            return false;
        }

        $count = $metrics->incrementViews($boost);

        if ($count > $boost->getImpressions()) {
            $expire->setBoost($boost);
            $expire->expire();
        }

        Counters::increment($boost->getEntity()->guid, "impression");
        Counters::increment($boost->getEntity()->owner_guid, "impression");

        try {
            $this->manager->record(
                (new View())
                    ->setEntityUrn($boost->getEntity()->getUrn())
                    ->setOwnerGuid((string) $boost->getEntity()->getOwnerGuid())
                    ->setClientMeta($this->clientMeta)
            );
        } catch (\Exception $e) {
            error_log($e);
        }

        $this->boostData = [
            'impressions' => $boost->getImpressions(),
            'impressions_met' => $count
        ];

        return true;
    }

    public function recordEntity(): bool
    {
        $entity = Entities\Factory::build($this->identifier);

        if (!$entity) {
            $this->lastError = 'Could not the entity';
            return false;
        }

        if ($entity->type === 'activity') {
            try {
                Core\Analytics\App::_()
                    ->setMetric('impression')
                    ->setKey($entity->guid)
                    ->increment();

                if ($entity->remind_object) {
                    Core\Analytics\App::_()
                        ->setMetric('impression')
                        ->setKey($entity->remind_object['guid'])
                        ->increment();

                    Core\Analytics\App::_()
                        ->setMetric('impression')
                        ->setKey($entity->remind_object['owner_guid'])
                        ->increment();
                }

                Core\Analytics\User::_()
                    ->setMetric('impression')
                    ->setKey($entity->owner_guid)
                    ->increment();
            } catch (\Exception $e) {
                error_log($e->getMessage());
            }
        }

        try {
            $this->manager->record(
                (new Core\Analytics\Views\View())
                    ->setEntityUrn($entity->getUrn())
                    ->setOwnerGuid((string) $entity->getOwnerGuid())
                    ->setClientMeta($this->clientMeta)
            );
        } catch (\Exception $e) {
            error_log($e);
        }

        Di::_()->get('Referrals\Cookie')
            ->setEntity($entity)
            ->create();
    }
}
+4 −0
Original line number Diff line number Diff line
@@ -44,6 +44,10 @@ class View
{
    use MagicAttributes;

    const TYPE_BOOST = 'boost';
    const TYPE_ENTITY = 'entity';
    const TYPE_ACTIVITY = 'activity';

    /** @var int */
    protected $year;

+32 −0
Original line number Diff line number Diff line
<?php

namespace Spec\Minds\Core\Analytics\Views;

use Minds\Core\Analytics\Views\Record;
use PhpSpec\ObjectBehavior;

class RecordSpec extends ObjectBehavior
{
    public function is_it_intializable()
    {
        $this->shouldHaveType(Record::class);
    }

    public function it_should_set_client_meta()
    {
        $this->setClientMeta([
                'page_token' => 'page_token_value',
                'position' => 'position_value',
                'platform' => 'platform_value',
                'source' => 'source_value',
                'medium' => 'medium_value',
                'campaign' => 'campaign_value',
                'delta' => 'delta_value',
            ])->shouldReturn($this);
    }

    public function it_should_set_identifier()
    {
        $this->setIdentifier('id_1')->shouldReturn($this);
    }
}