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
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Locked Files
Issues
143
Issues
143
List
Boards
Labels
Service Desk
Milestones
Merge Requests
27
Merge Requests
27
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
Compare Revisions
b109788aa1a07a70784e5c75d65143b00eefa0e7...7a06fe360fe10a68c5f32d94d5b9322d212882d4
Source
7a06fe360fe10a68c5f32d94d5b9322d212882d4
Select Git revision
...
Target
b109788aa1a07a70784e5c75d65143b00eefa0e7
Select Git revision
Compare
Commits (2)
(feat): Views core module
· 974b3abd
Emiliano Balbuena
authored
2 hours ago
974b3abd
Merge branch 'sprint/FunnyFrog.goal.analytics-views' into 'master'
· 7a06fe36
Mark Harding
authored
2 hours ago
(feat): Views core module See merge request
!183
7a06fe36
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
643 additions
and
1 deletion
+643
-1
views.php
Controllers/api/v2/analytics/views.php
+25
-0
Manager.php
Core/Analytics/Views/Manager.php
+43
-0
Repository.php
Core/Analytics/Views/Repository.php
+137
-0
View.php
Core/Analytics/Views/View.php
+100
-0
cassandra-provision.cql
Core/Provisioner/Provisioners/cassandra-provision.cql
+17
-1
ManagerSpec.php
Spec/Core/Analytics/Views/ManagerSpec.php
+61
-0
RepositorySpec.php
Spec/Core/Analytics/Views/RepositorySpec.php
+201
-0
ViewSpec.php
Spec/Core/Analytics/Views/ViewSpec.php
+58
-0
bootstrap.php
Spec/bootstrap.php
+1
-0
No files found.
Controllers/api/v2/analytics/views.php
View file @
7a06fe36
...
...
@@ -21,6 +21,8 @@ class views implements Interfaces\Api
public
function
post
(
$pages
)
{
$viewsManager
=
new
Core\Analytics\Views\Manager
();
switch
(
$pages
[
0
])
{
case
'boost'
:
$expire
=
Di
::
_
()
->
get
(
'Boost\Network\Expire'
);
...
...
@@ -47,6 +49,18 @@ class views implements Interfaces\Api
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
())
->
setClientMeta
(
$_POST
[
'client_meta'
]
??
[])
);
}
catch
(
\Exception
$e
)
{
error_log
(
$e
);
}
return
Factory
::
response
([
'status'
=>
'success'
,
'impressions'
=>
$boost
->
getImpressions
(),
...
...
@@ -88,6 +102,17 @@ class views implements Interfaces\Api
}
catch
(
\Exception
$e
)
{
error_log
(
$e
->
getMessage
());
}
try
{
$viewsManager
->
record
(
(
new
Core\Analytics\Views\View
())
->
setEntityUrn
(
$activity
->
getUrn
())
->
setClientMeta
(
$_POST
[
'client_meta'
]
??
[])
);
}
catch
(
\Exception
$e
)
{
error_log
(
$e
);
}
break
;
}
...
...
This diff is collapsed.
Click to expand it.
Core/Analytics/Views/Manager.php
0 → 100644
View file @
7a06fe36
<?php
/**
* Manager
* @author edgebal
*/
namespace
Minds\Core\Analytics\Views
;
use
Exception
;
class
Manager
{
/** @var Repository */
protected
$repository
;
public
function
__construct
(
$repository
=
null
)
{
$this
->
repository
=
$repository
?:
new
Repository
();
}
/**
* @param View $view
* @return bool
* @throws Exception
*/
public
function
record
(
View
$view
)
{
// Reset time fields and use current timestamp
$view
->
setYear
(
null
)
->
setMonth
(
null
)
->
setDay
(
null
)
->
setUuid
(
null
)
->
setTimestamp
(
time
());
// Add to repository
$this
->
repository
->
add
(
$view
);
return
true
;
}
}
This diff is collapsed.
Click to expand it.
Core/Analytics/Views/Repository.php
0 → 100644
View file @
7a06fe36
<?php
/**
* Repository
* @author edgebal
*/
namespace
Minds\Core\Analytics\Views
;
use
Cassandra\Rows
;
use
Cassandra\Timeuuid
;
use
Cassandra\Tinyint
;
use
DateTime
;
use
DateTimeZone
;
use
Exception
;
use
Minds\Common\Repository\Response
;
use
Minds\Core\Data\Cassandra\Client
as
CassandraClient
;
use
Minds\Core\Data\Cassandra\Prepared\Custom
;
use
Minds\Core\Di\Di
;
class
Repository
{
/** @var CassandraClient */
protected
$db
;
/**
* Repository constructor.
* @param CassandraClient $db
*/
public
function
__construct
(
$db
=
null
)
{
$this
->
db
=
$db
?:
Di
::
_
()
->
get
(
'Database\Cassandra\Cql'
);
}
/**
* @param array $opts
* @return Response
*/
public
function
getList
(
array
$opts
=
[])
{
$opts
=
array_merge
([
'limit'
=>
500
,
'offset'
=>
''
,
],
$opts
)
;
$cql
=
"SELECT * FROM views"
;
$values
=
[];
$cqlOpts
=
[];
// TODO: Implement constraints (by year/month/day/timeuuid)
if
(
$opts
[
'limit'
])
{
$cqlOpts
[
'page_size'
]
=
(
int
)
$opts
[
'limit'
];
}
if
(
$opts
[
'offset'
])
{
$cqlOpts
[
'paging_state_token'
]
=
base64_decode
(
$opts
[
'offset'
]);
}
$prepared
=
new
Custom
();
$prepared
->
query
(
$cql
,
$values
);
$prepared
->
setOpts
(
$opts
);
$response
=
new
Response
();
try
{
/** @var Rows $rows */
$rows
=
$this
->
db
->
request
(
$prepared
);
foreach
(
$rows
as
$row
)
{
$view
=
new
View
();
$view
->
setYear
((
int
)
$row
[
'year'
]
?:
null
)
->
setMonth
((
int
)
$row
[
'month'
]
?:
null
)
->
setDay
((
int
)
$row
[
'day'
]
?:
null
)
->
setUuid
(
$row
[
'uuid'
]
->
uuid
()
?:
null
)
->
setEntityUrn
(
$row
[
'entity_urn'
])
->
setPageToken
(
$row
[
'page_token'
])
->
setPosition
((
int
)
$row
[
'position'
])
->
setSource
(
$row
[
'platform'
])
->
setSource
(
$row
[
'source'
])
->
setMedium
(
$row
[
'medium'
])
->
setCampaign
(
$row
[
'campaign'
])
->
setDelta
((
int
)
$row
[
'delta'
])
->
setTimestamp
(
$row
[
'uuid'
]
->
time
());
$response
[]
=
$view
;
}
$response
->
setPagingToken
(
base64_encode
(
$rows
->
pagingStateToken
()));
$response
->
setLastPage
(
$rows
->
isLastPage
());
}
catch
(
Exception
$e
)
{
$response
->
setException
(
$e
);
}
return
$response
;
}
/**
* @param View $view
* @return bool
* @throws Exception
*/
public
function
add
(
View
$view
)
{
$timestamp
=
$view
->
getTimestamp
()
?:
time
();
$date
=
new
DateTime
(
"@
{
$timestamp
}
"
,
new
DateTimeZone
(
'utc'
));
$cql
=
"INSERT INTO views (year, month, day, uuid, entity_urn, page_token, position, platform, source, medium, campaign, delta) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
;
$values
=
[
(
int
)
(
$view
->
getYear
()
??
$date
->
format
(
'Y'
)),
new
Tinyint
((
int
)
(
$view
->
getMonth
()
??
$date
->
format
(
'm'
))),
new
Tinyint
((
int
)
(
$view
->
getDay
()
??
$date
->
format
(
'd'
))),
new
Timeuuid
(
$view
->
getUuid
()
??
$timestamp
*
1000
),
$view
->
getEntityUrn
()
?:
''
,
$view
->
getPageToken
()
?:
''
,
(
int
)
(
$view
->
getPosition
()
??
-
1
),
$view
->
getPlatform
()
?:
''
,
$view
->
getSource
()
?:
''
,
$view
->
getMedium
()
?:
''
,
$view
->
getCampaign
()
?:
''
,
(
int
)
(
$view
->
getDelta
()
??
0
),
];
$prepared
=
new
Custom
();
$prepared
->
query
(
$cql
,
$values
);
try
{
$this
->
db
->
request
(
$prepared
,
true
);
return
true
;
}
catch
(
Exception
$e
)
{
error_log
(
$e
);
return
false
;
}
}
}
This diff is collapsed.
Click to expand it.
Core/Analytics/Views/View.php
0 → 100644
View file @
7a06fe36
<?php
/**
* View
* @author edgebal
*/
namespace
Minds\Core\Analytics\Views
;
use
Minds\Traits\MagicAttributes
;
/**
* Class View
* @package Minds\Core\Analytics\Views
* @method View setYear(int $year)
* @method int getYear()
* @method View setMonth(int $month)
* @method int getMonth()
* @method View setDay(int $year)
* @method int getDay()
* @method View setUuid(string $uuid)
* @method string getUuid()
* @method View setEntityUrn(string $entityUrn)
* @method string getEntityUrn()
* @method View setPageToken(string $pageToken)
* @method string getPageToken()
* @method View setPosition(int $position)
* @method int getPosition()
* @method View setPlatform(string $platform)
* @method string getPlatform()
* @method View setSource(string $source)
* @method string getSource()
* @method View setMedium(string $medium)
* @method string getMedium()
* @method View setCampaign(string $campaign)
* @method string getCampaign()
* @method View setDelta(int $delta)
* @method int getDelta()
* @method View setTimestamp(int $timestamp)
* @method int getTimestamp()
*/
class
View
{
use
MagicAttributes
;
/** @var int */
protected
$year
;
/** @var int */
protected
$month
;
/** @var int */
protected
$day
;
/** @var string */
protected
$uuid
;
/** @var string */
protected
$entityUrn
;
/** @var string */
protected
$pageToken
;
/** @var int */
protected
$position
;
/** @var string */
protected
$platform
;
/** @var string */
protected
$source
;
/** @var string */
protected
$medium
;
/** @var string */
protected
$campaign
;
/** @var int */
protected
$delta
;
/** @var int */
protected
$timestamp
;
/**
* @param array $clientMeta
* @return $this
*/
public
function
setClientMeta
(
array
$clientMeta
)
{
$this
->
pageToken
=
$clientMeta
[
'page_token'
]
??
null
;
$this
->
position
=
$clientMeta
[
'position'
]
??
null
;
$this
->
platform
=
$clientMeta
[
'platform'
]
??
null
;
$this
->
source
=
$clientMeta
[
'source'
]
??
null
;
$this
->
medium
=
$clientMeta
[
'medium'
]
??
null
;
$this
->
campaign
=
$clientMeta
[
'campaign'
]
??
null
;
$this
->
delta
=
$clientMeta
[
'delta'
]
??
null
;
return
$this
;
}
}
This diff is collapsed.
Click to expand it.
Core/Provisioner/Provisioners/cassandra-provision.cql
View file @
7a06fe36
...
...
@@ -1370,4 +1370,20 @@ CREATE TABLE minds.sendwyre_accounts (
user_guid varint,
sendwyre_account_id text,
PRIMARY KEY (user_guid)
);
\ No newline at end of file
);
CREATE TABLE minds.views (
year int,
month tinyint,
day tinyint,
uuid timeuuid,
entity_urn text,
page_token text,
position int,
platform text,
source text,
medium text,
campaign text,
delta int,
PRIMARY KEY (year, month, day, uuid, entity_urn, page_token)
);
This diff is collapsed.
Click to expand it.
Spec/Core/Analytics/Views/ManagerSpec.php
0 → 100644
View file @
7a06fe36
<?php
namespace
Spec\Minds\Core\Analytics\Views
;
use
Minds\Core\Analytics\Views\Manager
;
use
Minds\Core\Analytics\Views\Repository
;
use
Minds\Core\Analytics\Views\View
;
use
PhpSpec\ObjectBehavior
;
use
Prophecy\Argument
;
class
ManagerSpec
extends
ObjectBehavior
{
/** @var Repository */
protected
$repository
;
function
let
(
Repository
$repository
)
{
$this
->
beConstructedWith
(
$repository
);
$this
->
repository
=
$repository
;
}
function
it_is_initializable
()
{
$this
->
shouldHaveType
(
Manager
::
class
);
}
function
it_should_record
(
View
$view
)
{
$view
->
setYear
(
null
)
->
shouldBeCalled
()
->
willReturn
(
$view
);
$view
->
setMonth
(
null
)
->
shouldBeCalled
()
->
willReturn
(
$view
);
$view
->
setDay
(
null
)
->
shouldBeCalled
()
->
willReturn
(
$view
);
$view
->
setUuid
(
null
)
->
shouldBeCalled
()
->
willReturn
(
$view
);
$view
->
setTimestamp
(
Argument
::
type
(
'int'
))
->
shouldBeCalled
()
->
willReturn
(
$view
);
$this
->
repository
->
add
(
$view
)
->
shouldBeCalled
()
->
willReturn
(
true
);
$this
->
record
(
$view
)
->
shouldReturn
(
true
);
}
}
This diff is collapsed.
Click to expand it.
Spec/Core/Analytics/Views/RepositorySpec.php
0 → 100644
View file @
7a06fe36
<?php
namespace
Spec\Minds\Core\Analytics\Views
;
use
Minds\Common\Repository\Response
;
use
Minds\Core\Analytics\Views\Repository
;
use
Minds\Core\Analytics\Views\View
;
use
Minds\Core\Data\Cassandra\Client
as
CassandraClient
;
use
Minds\Core\Data\Cassandra\Prepared\Custom
;
use
PhpSpec\Exception\Example\FailureException
;
use
PhpSpec\ObjectBehavior
;
use
Prophecy\Argument
;
class
RepositorySpec
extends
ObjectBehavior
{
/** @var CassandraClient */
protected
$db
;
function
let
(
CassandraClient
$db
)
{
$this
->
beConstructedWith
(
$db
);
$this
->
db
=
$db
;
}
function
it_is_initializable
()
{
$this
->
shouldHaveType
(
Repository
::
class
);
}
// function it_should_get_list()
// {
// }
function
it_should_add
(
View
$view
)
{
$now
=
strtotime
(
'2019-05-29 12:00:00+0000'
);
$view
->
getTimestamp
()
->
shouldBeCalled
()
->
willReturn
(
$now
);
$view
->
getYear
()
->
shouldBeCalled
()
->
willReturn
(
2019
);
$view
->
getMonth
()
->
shouldBeCalled
()
->
willReturn
(
5
);
$view
->
getDay
()
->
shouldBeCalled
()
->
willReturn
(
29
);
$view
->
getUuid
()
->
shouldBeCalled
()
->
willReturn
(
'abc-123-456-def'
);
$view
->
getEntityUrn
()
->
shouldBeCalled
()
->
willReturn
(
'urn:test:123123'
);
$view
->
getPageToken
()
->
shouldBeCalled
()
->
willReturn
(
'1234-qwe-qwe-1234'
);
$view
->
getPosition
()
->
shouldBeCalled
()
->
willReturn
(
5
);
$view
->
getPlatform
()
->
shouldBeCalled
()
->
willReturn
(
'php'
);
$view
->
getSource
()
->
shouldBeCalled
()
->
willReturn
(
'phpspec'
);
$view
->
getMedium
()
->
shouldBeCalled
()
->
willReturn
(
'test'
);
$view
->
getCampaign
()
->
shouldBeCalled
()
->
willReturn
(
'urn:phpspec:234234'
);
$view
->
getDelta
()
->
shouldBeCalled
()
->
willReturn
(
100
);
$this
->
db
->
request
(
Argument
::
that
(
function
(
Custom
$prepared
)
{
$statement
=
$prepared
->
build
();
return
stripos
(
$statement
[
'string'
],
'insert into views'
)
===
0
&&
$statement
[
'values'
][
0
]
===
2019
&&
$statement
[
'values'
][
1
]
->
toInt
()
===
5
&&
$statement
[
'values'
][
2
]
->
toInt
()
===
29
&&
$statement
[
'values'
][
3
]
->
uuid
()
===
'abc-123-456-def'
&&
$statement
[
'values'
][
4
]
===
'urn:test:123123'
&&
$statement
[
'values'
][
5
]
===
'1234-qwe-qwe-1234'
&&
$statement
[
'values'
][
6
]
===
5
&&
$statement
[
'values'
][
7
]
===
'php'
&&
$statement
[
'values'
][
8
]
===
'phpspec'
&&
$statement
[
'values'
][
9
]
===
'test'
&&
$statement
[
'values'
][
10
]
===
'urn:phpspec:234234'
&&
$statement
[
'values'
][
11
]
===
100
;
}),
true
)
->
shouldBeCalled
()
->
willReturn
(
true
);
$this
->
add
(
$view
)
->
shouldReturn
(
true
);
}
function
it_should_add_with_a_timestamp
(
View
$view
)
{
$now
=
strtotime
(
'2019-05-29 12:00:00+0000'
);
$view
->
getTimestamp
()
->
shouldBeCalled
()
->
willReturn
(
$now
);
$view
->
getYear
()
->
shouldBeCalled
()
->
willReturn
(
null
);
$view
->
getMonth
()
->
shouldBeCalled
()
->
willReturn
(
null
);
$view
->
getDay
()
->
shouldBeCalled
()
->
willReturn
(
null
);
$view
->
getUuid
()
->
shouldBeCalled
()
->
willReturn
(
null
);
$view
->
getEntityUrn
()
->
shouldBeCalled
()
->
willReturn
(
'urn:test:123123'
);
$view
->
getPageToken
()
->
shouldBeCalled
()
->
willReturn
(
'1234-qwe-qwe-1234'
);
$view
->
getPosition
()
->
shouldBeCalled
()
->
willReturn
(
5
);
$view
->
getPlatform
()
->
shouldBeCalled
()
->
willReturn
(
'php'
);
$view
->
getSource
()
->
shouldBeCalled
()
->
willReturn
(
'phpspec'
);
$view
->
getMedium
()
->
shouldBeCalled
()
->
willReturn
(
'test'
);
$view
->
getCampaign
()
->
shouldBeCalled
()
->
willReturn
(
'urn:phpspec:234234'
);
$view
->
getDelta
()
->
shouldBeCalled
()
->
willReturn
(
100
);
$this
->
db
->
request
(
Argument
::
that
(
function
(
Custom
$prepared
)
use
(
$now
)
{
$statement
=
$prepared
->
build
();
return
stripos
(
$statement
[
'string'
],
'insert into views'
)
===
0
&&
$statement
[
'values'
][
0
]
===
2019
&&
$statement
[
'values'
][
1
]
->
toInt
()
===
5
&&
$statement
[
'values'
][
2
]
->
toInt
()
===
29
&&
$statement
[
'values'
][
3
]
->
time
()
===
$now
*
1000
&&
$statement
[
'values'
][
4
]
===
'urn:test:123123'
&&
$statement
[
'values'
][
5
]
===
'1234-qwe-qwe-1234'
&&
$statement
[
'values'
][
6
]
===
5
&&
$statement
[
'values'
][
7
]
===
'php'
&&
$statement
[
'values'
][
8
]
===
'phpspec'
&&
$statement
[
'values'
][
9
]
===
'test'
&&
$statement
[
'values'
][
10
]
===
'urn:phpspec:234234'
&&
$statement
[
'values'
][
11
]
===
100
;
}),
true
)
->
shouldBeCalled
()
->
willReturn
(
true
);
$this
->
add
(
$view
)
->
shouldReturn
(
true
);
}
}
This diff is collapsed.
Click to expand it.
Spec/Core/Analytics/Views/ViewSpec.php
0 → 100644
View file @
7a06fe36
<?php
namespace
Spec\Minds\Core\Analytics\Views
;
use
Minds\Core\Analytics\Views\View
;
use
PhpSpec\ObjectBehavior
;
use
Prophecy\Argument
;
class
ViewSpec
extends
ObjectBehavior
{
function
it_is_initializable
()
{
$this
->
shouldHaveType
(
View
::
class
);
}
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
);
$this
->
getPageToken
()
->
shouldReturn
(
'page_token_value'
);
$this
->
getPosition
()
->
shouldReturn
(
'position_value'
);
$this
->
getPlatform
()
->
shouldReturn
(
'platform_value'
);
$this
->
getSource
()
->
shouldReturn
(
'source_value'
);
$this
->
getMedium
()
->
shouldReturn
(
'medium_value'
);
$this
->
getCampaign
()
->
shouldReturn
(
'campaign_value'
);
$this
->
getDelta
()
->
shouldReturn
(
'delta_value'
);
}
}
This diff is collapsed.
Click to expand it.
Spec/bootstrap.php
View file @
7a06fe36
...
...
@@ -297,6 +297,7 @@ if (!class_exists('Cassandra')) {
class_alias
(
'MockSet'
,
'Cassandra\Set'
);
class_alias
(
'MockMap'
,
'Cassandra\Map'
);
class_alias
(
'Mock'
,
'Cassandra\Uuid'
);
class_alias
(
'Mock'
,
'Cassandra\Timeuuid'
);
class_alias
(
'Mock'
,
'Cassandra\Boolean'
);
class_alias
(
'Mock'
,
'MongoDB\BSON\UTCDateTime'
);
class_alias
(
'Mock'
,
'Cassandra\RetryPolicy\Logging'
);
...
...
This diff is collapsed.
Click to expand it.