Skip to content
Next
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Switch to GitLab Next
Sign in / Register
Toggle navigation
Minds Backend - Engine
Project
Project
Details
Activity
Releases
Dependency List
Cycle Analytics
Insights
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Locked Files
Issues
148
Issues
148
List
Boards
Labels
Service Desk
Milestones
Merge Requests
49
Merge Requests
49
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Minds
Minds Backend - Engine
Commits
434afa0a
Commit
434afa0a
authored
2 minutes ago
by
Emiliano Balbuena
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
(wip): Metrics
parent
78104aa8
goal/boost-campaigns-e24
1 merge request
!235
WIP: Boost Campaigns (&24)
Pipeline
#70348276
pending with stages
Changes
9
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
378 additions
and
8 deletions
+378
-8
views.php
Controllers/api/v2/analytics/views.php
+44
-2
BoostProvider.php
Core/Boost/BoostProvider.php
+3
-0
Campaign.php
Core/Boost/Campaigns/Campaign.php
+9
-1
Dispatcher.php
Core/Boost/Campaigns/Dispatcher.php
+18
-1
Manager.php
Core/Boost/Campaigns/Manager.php
+27
-0
Metrics.php
Core/Boost/Campaigns/Metrics.php
+123
-0
CountersProvider.php
Core/Counters/CountersProvider.php
+19
-0
Manager.php
Core/Counters/Manager.php
+129
-0
Resolver.php
Core/Entities/Resolver.php
+6
-4
No files found.
Controllers/api/v2/analytics/views.php
View file @
434afa0a
...
...
@@ -5,6 +5,7 @@ namespace Minds\Controllers\api\v2\analytics;
use
Minds\Api\Factory
;
use
Minds\Common\Urn
;
use
Minds\Core
;
use
Minds\Core\Di\Di
;
use
Minds\Entities
;
...
...
@@ -23,14 +24,55 @@ class views implements Interfaces\Api
{
$viewsManager
=
new
Core\Analytics\Views\Manager
();
/** @var Core\Boost\Campaigns\Manager $campaignsManager */
$campaignsManager
=
Di
::
_
()
->
get
(
'Boost\Campaigns\Manager'
);
/** @var Core\Boost\Campaigns\Metrics $campaignsMetricsManager */
$campaignsMetricsManager
=
Di
::
_
()
->
get
(
'Boost\Campaigns\Metrics'
);
switch
(
$pages
[
0
])
{
case
'boost'
:
$urn
=
new
Urn
(
is_numeric
(
$pages
[
1
])
?
"urn:boost:newsfeed:
{
$pages
[
1
]
}
"
:
$pages
[
1
]
);
if
(
$urn
->
getNid
()
===
'campaign'
)
{
// Boost Campaigns
try
{
$campaign
=
$campaignsManager
->
get
((
string
)
$urn
);
$campaignsMetricsManager
->
setCampaign
(
$campaign
)
->
increment
();
// NOTE: Campaigns have a _single_ entity, for now. Refactor this when we support multiple
// Ideally, we should use a composite URN, like: urn:campaign-entity:100000321:(urn:activity:100000500)
foreach
(
$campaign
->
getEntityUrns
()
as
$entityUrn
)
{
$viewsManager
->
record
(
(
new
Core\Analytics\Views\View
())
->
setEntityUrn
(
$entityUrn
)
->
setClientMeta
(
$_POST
[
'client_meta'
]
??
[])
);
}
}
catch
(
\Exception
$e
)
{
return
Factory
::
response
([
'status'
=>
'error'
,
'message'
=>
$e
->
getMessage
(),
]);
}
return
Factory
::
response
([]);
}
$urn
=
(
string
)
$urn
;
$expire
=
Di
::
_
()
->
get
(
'Boost\Network\Expire'
);
$metrics
=
Di
::
_
()
->
get
(
'Boost\Network\Metrics'
);
$manager
=
Di
::
_
()
->
get
(
'Boost\Network\Manager'
);
$urn
=
"urn:boost:newsfeed:
{
$pages
[
1
]
}
"
;
$boost
=
$manager
->
get
(
$urn
,
[
'hydrate'
=>
true
]);
if
(
!
$boost
)
{
return
Factory
::
response
([
...
...
This diff is collapsed.
Click to expand it.
Core/Boost/BoostProvider.php
View file @
434afa0a
...
...
@@ -62,6 +62,9 @@ class BoostProvider extends Provider
$this
->
di
->
bind
(
'Boost\Campaigns\Dispatcher'
,
function
(
$di
)
{
return
new
Campaigns\Dispatcher
();
},
[
'useFactory'
=>
true
]);
$this
->
di
->
bind
(
'Boost\Campaigns\Metrics'
,
function
(
$di
)
{
return
new
Campaigns\Metrics
();
},
[
'useFactory'
=>
true
]);
$this
->
di
->
bind
(
'Boost\Campaigns\Manager'
,
function
(
$di
)
{
return
new
Campaigns\Manager
();
},
[
'useFactory'
=>
true
]);
...
...
This diff is collapsed.
Click to expand it.
Core/Boost/Campaigns/Campaign.php
View file @
434afa0a
...
...
@@ -217,6 +217,14 @@ class Campaign implements JsonSerializable
return
(
$this
->
budget
/
$this
->
impressions
)
*
1000
;
}
/**
* @return bool
*/
public
function
isDelivering
()
{
return
$this
->
getDeliveryStatus
()
===
static
::
APPROVED_STATUS
;
}
/**
* @param $now
* @return bool
...
...
@@ -235,7 +243,7 @@ class Campaign implements JsonSerializable
*/
public
function
shouldBeCompleted
(
$now
)
{
$isDelivering
=
$this
->
getDeliveryStatus
()
!==
static
::
CREATED_STATUS
;
$isDelivering
=
$this
->
isDelivering
()
;
$ended
=
$now
>=
$this
->
getEnd
();
$fulfilled
=
$this
->
getImpressionsMet
()
>=
$this
->
getImpressions
();
...
...
This diff is collapsed.
Click to expand it.
Core/Boost/Campaigns/Dispatcher.php
View file @
434afa0a
...
...
@@ -13,21 +13,28 @@ class Dispatcher
/** @var Manager */
protected
$manager
;
/** @var Metrics */
protected
$metrics
;
/**
* Dispatcher constructor.
* @param Manager $manager
* @param Metrics $metrics
* @throws Exception
*/
public
function
__construct
(
$manager
=
null
$manager
=
null
,
$metrics
=
null
)
{
$this
->
manager
=
$manager
?:
new
Manager
();
$this
->
metrics
=
$metrics
?:
new
Metrics
();
}
/**
* @param Campaign $campaignRef
* @throws CampaignException
* @throws Exception
*/
public
function
onLifecycle
(
Campaign
$campaignRef
)
{
...
...
@@ -35,6 +42,16 @@ class Dispatcher
$campaign
=
$this
->
manager
->
get
(
$campaignRef
->
getUrn
());
if
(
$campaign
->
isDelivering
())
{
$campaign
=
$this
->
metrics
->
setCampaign
(
$campaign
)
->
syncImpressionsMet
();
// TODO: Save campaign every 10/20 impressions to avoid ES overloading
error_log
(
"[BoostCampaignsDispatcher] Saving updated
{
$campaign
->
getUrn
()
}
..."
);
$this
->
manager
->
sync
(
$campaign
);
}
if
(
$campaign
->
shouldBeCompleted
(
$now
))
{
error_log
(
"[BoostCampaignsDispatcher] Completing
{
$campaign
->
getUrn
()
}
..."
);
$this
->
manager
->
complete
(
$campaign
);
...
...
This diff is collapsed.
Click to expand it.
Core/Boost/Campaigns/Manager.php
View file @
434afa0a
...
...
@@ -289,6 +289,33 @@ class Manager
return
$campaign
;
}
/**
* @param Campaign $campaign
* @return Campaign
* @throws Exception
*/
public
function
sync
(
Campaign
$campaign
)
{
$this
->
repository
->
update
(
$campaign
);
$this
->
elasticRepository
->
update
(
$campaign
);
return
$campaign
;
}
/**
* @param Campaign $campaignRef
*/
public
function
onImpression
(
Campaign
$campaignRef
)
{
// Queue for lifecycle events
$this
->
queueClient
->
setQueue
(
'BoostCampaignDispatcher'
)
->
send
([
'campaign'
=>
serialize
(
$campaignRef
),
]);
}
/**
* @param Campaign $campaignRef
* @return Campaign
...
...
This diff is collapsed.
Click to expand it.
Core/Boost/Campaigns/Metrics.php
0 → 100644
View file @
434afa0a
<?php
/**
* Metrics
* @author edgebal
*/
namespace
Minds\Core\Boost\Campaigns
;
use
Exception
;
use
Minds\Common\Urn
;
use
Minds\Core\Counters\Manager
as
Counters
;
use
Minds\Core\Di\Di
;
use
Minds\Core\Entities\Resolver
;
class
Metrics
{
/** @var Manager */
protected
$manager
;
/** @var Counters */
protected
$counters
;
/** @var Resolver */
protected
$resolver
;
/** @var Campaign */
protected
$campaign
;
/**
* Metrics constructor.
* @param Manager $manager
* @param Counters $counters
* @param Resolver $resolver
* @throws Exception
*/
public
function
__construct
(
$manager
=
null
,
$counters
=
null
,
$resolver
=
null
)
{
$this
->
manager
=
$manager
?:
new
Manager
();
$this
->
counters
=
$counters
?:
Di
::
_
()
->
get
(
'Counters'
);
$this
->
resolver
=
$resolver
?:
new
Resolver
();
}
/**
* @param Campaign|Urn|string $campaign
* @return Metrics
* @throws Exception
*/
public
function
setCampaign
(
$campaign
)
{
if
(
is_object
(
$campaign
)
&&
$campaign
instanceof
Campaign
)
{
$this
->
campaign
=
$campaign
;
}
else
{
$this
->
campaign
=
$this
->
manager
->
get
((
string
)
$campaign
);
}
return
$this
;
}
/**
* @return bool
* @throws Exception
*/
public
function
increment
()
{
// Increment general boosts counter
$this
->
counters
->
setEntityGuid
(
0
)
->
setMetric
(
'boost_impressions'
)
->
increment
();
// Increment boost counter
$this
->
counters
->
setEntityGuid
(
$this
->
campaign
->
getGuid
())
->
setMetric
(
'boost_impressions'
)
->
increment
();
// Pass down impressions update to manager
$this
->
manager
->
onImpression
(
$this
->
campaign
);
// Increment entity counters
// NOTE: Campaigns have a _single_ entity, for now. Refactor this when we support multiple
// Ideally, we should use a composite URN, like: urn:campaign-entity:100000321:(urn:activity:100000500)
foreach
(
$this
->
campaign
->
getEntityUrns
()
as
$entityUrn
)
{
$entity
=
$this
->
resolver
->
setOpts
([
'ignoreAcl'
=>
true
])
->
single
(
$entityUrn
);
$this
->
counters
->
setEntityGuid
(
$entity
->
guid
)
->
setMetric
(
'impression'
)
->
increment
();
$this
->
counters
->
setEntityGuid
(
$entity
->
owner_guid
)
->
setMetric
(
'impression'
)
->
increment
();
}
return
true
;
}
/**
* @return Campaign
* @throws Exception
*/
public
function
syncImpressionsMet
()
{
$count
=
$this
->
counters
->
setEntityGuid
(
$this
->
campaign
->
getGuid
())
->
setMetric
(
'boost_impressions'
)
->
get
(
false
);
$this
->
campaign
->
setImpressionsMet
(
$count
);
return
$this
->
campaign
;
}
}
This diff is collapsed.
Click to expand it.
Core/Counters/CountersProvider.php
0 → 100644
View file @
434afa0a
<?php
/**
* CountersProvider
* @author edgebal
*/
namespace
Minds\Core\Counters
;
use
Minds\Core\Di\Provider
;
class
CountersProvider
extends
Provider
{
public
function
register
()
{
$this
->
di
->
bind
(
'Counters'
,
function
(
$di
)
{
return
new
Manager
();
},
[
'useFactory'
=>
true
]);
}
}
This diff is collapsed.
Click to expand it.
Core/Counters/Manager.php
0 → 100644
View file @
434afa0a
<?php
/**
* Manager
* @author edgebal
*/
namespace
Minds\Core\Counters
;
use
Exception
;
use
Minds\Core\Data\Cassandra\Client
as
CassandraClient
;
use
Minds\Core\Di\Di
;
use
Minds\Helpers\Counters
;
class
Manager
{
/** @var CassandraClient */
protected
$dbClient
;
/** @var int|string */
protected
$entityGuid
;
/** @var string */
protected
$metric
;
/**
* Manager constructor.
* @param CassandraClient $dbClient
*/
public
function
__construct
(
$dbClient
=
null
)
{
$this
->
dbClient
=
$dbClient
?:
Di
::
_
()
->
get
(
'Database\Cassandra\Cql'
);
}
/**
* @param int|string $entityGuid
* @return Manager
*/
public
function
setEntityGuid
(
$entityGuid
)
{
$this
->
entityGuid
=
$entityGuid
;
return
$this
;
}
/**
* @param string $metric
* @return Manager
*/
public
function
setMetric
(
string
$metric
)
{
$this
->
metric
=
$metric
;
return
$this
;
}
/**
* @param int $value
* @return bool
* @throws Exception
*/
public
function
increment
(
$value
=
1
)
{
if
(
!
$this
->
entityGuid
)
{
throw
new
Exception
(
'Invalid counter entity'
);
}
if
(
!
$this
->
metric
)
{
throw
new
Exception
(
'Invalid counter metric'
);
}
Counters
::
increment
(
$this
->
entityGuid
,
$this
->
metric
,
$value
,
$this
->
dbClient
);
return
true
;
}
/**
* @param int $value
* @return bool
* @throws Exception
*/
public
function
decrement
(
$value
=
1
)
{
if
(
!
$this
->
entityGuid
)
{
throw
new
Exception
(
'Invalid counter entity'
);
}
if
(
!
$this
->
metric
)
{
throw
new
Exception
(
'Invalid counter metric'
);
}
Counters
::
decrement
(
$this
->
entityGuid
,
$this
->
metric
,
$value
,
$this
->
dbClient
);
return
true
;
}
/**
* @param bool $cache
* @return int
* @throws Exception
*/
public
function
get
(
$cache
=
true
)
{
if
(
!
$this
->
entityGuid
)
{
throw
new
Exception
(
'Invalid counter entity'
);
}
if
(
!
$this
->
metric
)
{
throw
new
Exception
(
'Invalid counter metric'
);
}
return
Counters
::
get
(
$this
->
entityGuid
,
$this
->
metric
,
$cache
,
$this
->
dbClient
);
}
/**
* @return bool
* @throws Exception
*/
public
function
clear
()
{
if
(
!
$this
->
entityGuid
)
{
throw
new
Exception
(
'Invalid counter entity'
);
}
if
(
!
$this
->
metric
)
{
throw
new
Exception
(
'Invalid counter metric'
);
}
Counters
::
clear
(
$this
->
entityGuid
,
$this
->
metric
,
0
,
$this
->
dbClient
);
return
true
;
}
}
This diff is collapsed.
Click to expand it.
Core/Entities/Resolver.php
View file @
434afa0a
...
...
@@ -124,12 +124,14 @@ class Resolver
$sorted
=
array_filter
(
$sorted
,
function
(
$entity
)
{
return
(
bool
)
$entity
;
});
// Filter out forbidden entities
// Filter out forbidden entities
, if not ignoring ACL
$sorted
=
array_filter
(
$sorted
,
function
(
$entity
)
{
return
$this
->
acl
->
read
(
$entity
,
$this
->
user
);
if
(
!
(
$this
->
opts
[
'ignoreAcl'
]
??
false
))
{
$sorted
=
array_filter
(
$sorted
,
function
(
$entity
)
{
return
$this
->
acl
->
read
(
$entity
,
$this
->
user
);
//&& !Flags::shouldFail($entity);
});
});
}
//
...
...
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment