Skip to content
GitLab
Menu
Why GitLab
Pricing
Contact Sales
Explore
Why GitLab
Pricing
Contact Sales
Explore
Sign in
Get free trial
Commits on Source (2)
(wip): partner earnings
· 474516ab
Mark Harding
authored
Oct 11, 2019
474516ab
(chore): various fixes and changes to dashboards
· cfaac31d
Mark Harding
authored
Oct 11, 2019
cfaac31d
Hide whitespace changes
Inline
Side-by-side
Controllers/Cli/PartnerEarnings.php
0 → 100644
View file @
cfaac31d
<?php
namespace
Minds\Controllers\Cli
;
use
Minds\Core
;
use
Minds\Core\Monetization\Partners\Manager
;
use
Minds\Cli
;
use
Minds\Interfaces
;
use
Minds\Exceptions
;
use
Minds\Entities
;
class
PartnerEarnings
extends
Cli\Controller
implements
Interfaces\CliControllerInterface
{
public
function
__construct
()
{
}
public
function
help
(
$command
=
null
)
{
$this
->
out
(
'TBD'
);
}
public
function
exec
()
{
$this
->
out
(
'Missing subcommand'
);
}
public
function
sync
()
{
error_reporting
(
E_ALL
);
ini_set
(
'display_errors'
,
1
);
$daysAgo
=
$this
->
getOpt
(
'daysAgo'
)
?:
0
;
$from
=
$this
->
getOpt
(
'from'
)
?:
strtotime
(
"midnight
$daysAgo
days ago"
);
$manager
=
new
Manager
();
$i
=
0
;
foreach
(
$manager
->
issueDeposits
([
'from'
=>
$from
])
as
$record
)
{
$this
->
out
(
++
$i
);
}
}
}
Core/Analytics/Dashboards/EarningsDashboard.php
0 → 100644
View file @
cfaac31d
<?php
/**
* Earnings Dashboard
*/
namespace
Minds\Core\Analytics\Dashboards
;
use
Minds\Traits\MagicAttributes
;
/**
* @method TrafficDashboard setTimespanId(string $timespanId)
* @method TrafficDashboard setFilterIds(array $filtersIds)
*/
class
EarningsDashboard
implements
DashboardInterface
{
use
MagicAttributes
;
/** @var string */
private
$timespanId
=
'30d'
;
/** @var string[] */
private
$filterIds
=
[
'platform::browser'
];
/** @var string */
private
$metricId
=
'active_users'
;
/** @var Timespans\TimespansCollection */
private
$timespansCollection
;
/** @var Metrics\MetricsCollection */
private
$metricsCollection
;
/** @var Filters\FiltersCollection */
private
$filtersCollection
;
/** @var Visualisations\Chart\ChartSegmentsCollection */
private
$chartCollection
;
public
function
__construct
(
$timespansCollection
=
null
,
$metricsCollection
=
null
,
$filtersCollection
=
null
)
{
$this
->
timespansCollection
=
$timespansCollection
??
new
Timespans\TimespansCollection
();
$this
->
metricsCollection
=
$metricsCollection
??
new
Metrics\MetricsCollection
();
$this
->
filtersCollection
=
$filtersCollection
??
new
Filters\FiltersCollection
();
}
/**
* Build the dashboard
* @return self
*/
public
function
build
():
self
{
$this
->
timespansCollection
->
setSelectedId
(
$this
->
timespanId
)
->
addTimespans
(
new
Timespans\TodayTimespan
(),
new
Timespans\_30dTimespan
(),
new
Timespans\_1yTimespan
(),
new
Timespans\MtdTimespan
(),
new
Timespans\YtdTimespan
()
);
$this
->
filtersCollection
->
setSelectedIds
(
$this
->
filterIds
)
->
addFilters
(
new
Filters\ChannelFilter
()
);
$this
->
metricsCollection
->
setTimespansCollection
(
$this
->
timespansCollection
)
->
setFiltersCollection
(
$this
->
filtersCollection
)
->
setSelectedId
(
$this
->
metricId
)
->
addMetrics
(
new
Metrics\Earnings\TotalEarningsMetric
(),
new
Metrics\Earnings\ViewsEarningsMetric
(),
new
Metrics\Earnings\ReferralsEarningsMetric
(),
new
Metrics\Earnings\SalesEarningsMetric
()
)
->
build
();
return
$this
;
}
/**
* Export
* @param array $extras
* @return array
*/
public
function
export
(
array
$extras
=
[]):
array
{
$this
->
build
();
return
[
'category'
=>
'earnings'
,
'timespan'
=>
$this
->
timespansCollection
->
getSelected
()
->
getId
(),
'timespans'
=>
$this
->
timespansCollection
->
export
(),
'metric'
=>
$this
->
metricsCollection
->
getSelected
()
->
getId
(),
'metrics'
=>
$this
->
metricsCollection
->
export
(),
'filter'
=>
$this
->
filtersCollection
->
getSelectedIds
(),
'filters'
=>
$this
->
filtersCollection
->
export
(),
];
}
}
Core/Analytics/Dashboards/Manager.php
View file @
cfaac31d
...
@@ -6,6 +6,7 @@ class Manager
...
@@ -6,6 +6,7 @@ class Manager
const
DASHBOARDS
=
[
const
DASHBOARDS
=
[
'traffic'
=>
TrafficDashboard
::
class
,
'traffic'
=>
TrafficDashboard
::
class
,
'trending'
=>
TrendingDashboard
::
class
,
'trending'
=>
TrendingDashboard
::
class
,
'earnings'
=>
EarningsDashboard
::
class
,
];
];
/**
/**
...
...
Core/Analytics/Dashboards/Metrics/AbstractMetric.php
View file @
cfaac31d
...
@@ -3,6 +3,7 @@ namespace Minds\Core\Analytics\Dashboards\Metrics;
...
@@ -3,6 +3,7 @@ namespace Minds\Core\Analytics\Dashboards\Metrics;
use
Minds\Core\Analytics\Dashboards\Timespans\TimespansCollection
;
use
Minds\Core\Analytics\Dashboards\Timespans\TimespansCollection
;
use
Minds\Core\Di\Di
;
use
Minds\Core\Di\Di
;
use
Minds\Core\Session
;
use
Minds\Traits\MagicAttributes
;
use
Minds\Traits\MagicAttributes
;
/**
/**
...
@@ -43,6 +44,37 @@ abstract class AbstractMetric
...
@@ -43,6 +44,37 @@ abstract class AbstractMetric
/** @var FiltersCollection */
/** @var FiltersCollection */
protected
$filtersCollection
;
protected
$filtersCollection
;
/**
* Return the usd guid for metrics
* @return string
*/
protected
function
getUserGuid
():
?string
{
$filters
=
$this
->
filtersCollection
->
getSelected
();
$channelFilter
=
$filters
[
'channel'
];
if
(
!
$channelFilter
)
{
if
(
!
Session
::
getLoggedInUserGuid
())
{
throw
new
\Exception
(
"You must be loggedin"
);
}
return
Session
::
getLoggedInUserGuid
();
}
if
(
$channelFilter
->
getSelectedOption
()
===
'all'
)
{
if
(
Session
::
isAdmin
())
{
return
""
;
}
$channelFilter
->
setSelectedOption
(
'self'
);
}
if
(
$channelFilter
->
getSelectedOption
()
===
'self'
)
{
return
Session
::
getLoggedInUserGuid
();
}
// TODO: check permissions first
return
$channelFilter
->
getSelectedOption
();
}
/**
/**
* Export
* Export
* @param array $extras
* @param array $extras
...
...
Core/Analytics/Dashboards/Metrics/ActiveUsersMetric.php
View file @
cfaac31d
...
@@ -32,6 +32,10 @@ class ActiveUsersMetric extends AbstractMetric
...
@@ -32,6 +32,10 @@ class ActiveUsersMetric extends AbstractMetric
*/
*/
public
function
buildSummary
():
self
public
function
buildSummary
():
self
{
{
if
(
$this
->
getUserGuid
())
{
return
$this
;
}
$timespan
=
$this
->
timespansCollection
->
getSelected
();
$timespan
=
$this
->
timespansCollection
->
getSelected
();
$filters
=
$this
->
filtersCollection
->
getSelected
();
$filters
=
$this
->
filtersCollection
->
getSelected
();
...
@@ -118,6 +122,11 @@ class ActiveUsersMetric extends AbstractMetric
...
@@ -118,6 +122,11 @@ class ActiveUsersMetric extends AbstractMetric
*/
*/
public
function
buildVisualisation
():
self
public
function
buildVisualisation
():
self
{
{
if
(
$this
->
getUserGuid
())
{
$this
->
visualisation
=
(
new
Visualisations\ChartVisualisation
());
return
$this
;
}
$timespan
=
$this
->
timespansCollection
->
getSelected
();
$timespan
=
$this
->
timespansCollection
->
getSelected
();
$xValues
=
[];
$xValues
=
[];
$yValues
=
[];
$yValues
=
[];
...
...
Core/Analytics/Dashboards/Metrics/Earnings/AbstractEarningsMetric.php
0 → 100644
View file @
cfaac31d
<?php
namespace
Minds\Core\Analytics\Dashboards\Metrics\Earnings
;
use
Minds\Core\Di\Di
;
use
Minds\Core\Session
;
use
Minds\Core\Data\ElasticSearch
;
use
Minds\Core\Analytics\Dashboards\Metrics\AbstractMetric
;
use
Minds\Core\Analytics\Dashboards\Metrics\MetricSummary
;
use
Minds\Core\Analytics\Dashboards\Metrics\Visualisations
;
abstract
class
AbstractEarningsMetric
extends
AbstractMetric
{
/** @var Elasticsearch\Client */
private
$es
;
/** @var string */
protected
$id
=
''
;
/** @var string */
protected
$label
=
''
;
/** @var string */
protected
$description
=
''
;
/** @var array */
protected
$permissions
=
[
'user'
,
'admin'
];
/** @var string */
protected
$unit
=
'usd'
;
/** @var string */
protected
$aggField
=
''
;
public
function
__construct
(
$es
=
null
)
{
$this
->
es
=
$es
??
Di
::
_
()
->
get
(
'Database\ElasticSearch'
);
}
/**
* Build the metrics
* @return self
*/
public
function
buildSummary
():
self
{
$timespan
=
$this
->
timespansCollection
->
getSelected
();
$filters
=
$this
->
filtersCollection
->
getSelected
();
$comparisonTsMs
=
strtotime
(
"midnight -
{
$timespan
->
getComparisonInterval
()
}
days"
,
$timespan
->
getFromTsMs
()
/
1000
)
*
1000
;
$currentTsMs
=
$timespan
->
getFromTsMs
();
$values
=
[];
foreach
([
'value'
=>
$currentTsMs
,
'comparison'
=>
$comparisonTsMs
]
as
$key
=>
$tsMs
)
{
$must
=
[];
$must
[][
'range'
]
=
[
'@timestamp'
=>
[
'gte'
=>
$tsMs
,
'lte'
=>
strtotime
(
"midnight +
{
$timespan
->
getComparisonInterval
()
}
days"
,
$tsMs
/
1000
)
*
1000
,
],
];
if
(
$userGuid
=
$this
->
getUserGuid
())
{
$must
[]
=
[
'term'
=>
[
'owner_guid'
=>
$userGuid
,
],
];
}
$query
=
[
'index'
=>
'minds-entitycentric-*'
,
'size'
=>
0
,
'body'
=>
[
'query'
=>
[
'bool'
=>
[
'must'
=>
$must
,
],
],
'aggs'
=>
[
'1'
=>
[
'sum'
=>
[
'field'
=>
$this
->
aggField
,
],
],
],
],
];
// Query elasticsearch
$prepared
=
new
ElasticSearch\Prepared\Search
();
$prepared
->
query
(
$query
);
$response
=
$this
->
es
->
request
(
$prepared
);
$values
[
$key
]
=
$response
[
'aggregations'
][
'1'
][
'value'
];
}
$this
->
summary
=
new
MetricSummary
();
$this
->
summary
->
setValue
(
$values
[
'value'
])
->
setComparisonValue
(
$values
[
'comparison'
])
->
setComparisonInterval
(
$timespan
->
getComparisonInterval
())
->
setComparisonPositivity
(
true
);
return
$this
;
}
/**
* Build a visualisation for the metric
* @return self
*/
public
function
buildVisualisation
():
self
{
$timespan
=
$this
->
timespansCollection
->
getSelected
();
$filters
=
$this
->
filtersCollection
->
getSelected
();
$must
=
[];
// Range must be from previous period
$must
[][
'range'
]
=
[
'@timestamp'
=>
[
'gte'
=>
$timespan
->
getFromTsMs
(),
],
];
if
(
$userGuid
=
$this
->
getUserGuid
())
{
$must
[]
=
[
'term'
=>
[
'owner_guid'
=>
$userGuid
,
],
];
}
// Do the query
$query
=
[
'index'
=>
'minds-entitycentric-*'
,
'size'
=>
0
,
'body'
=>
[
'query'
=>
[
'bool'
=>
[
'must'
=>
$must
,
],
],
'aggs'
=>
[
'1'
=>
[
'date_histogram'
=>
[
'field'
=>
'@timestamp'
,
'interval'
=>
$timespan
->
getInterval
(),
'min_doc_count'
=>
1
,
],
'aggs'
=>
[
'2'
=>
[
'sum'
=>
[
'field'
=>
$this
->
aggField
,
],
],
],
],
],
],
];
// Query elasticsearch
$prepared
=
new
ElasticSearch\Prepared\Search
();
$prepared
->
query
(
$query
);
$response
=
$this
->
es
->
request
(
$prepared
);
$buckets
=
[];
foreach
(
$response
[
'aggregations'
][
'1'
][
'buckets'
]
as
$bucket
)
{
$date
=
date
(
Visualisations\ChartVisualisation
::
DATE_FORMAT
,
$bucket
[
'key'
]
/
1000
);
$buckets
[]
=
[
'key'
=>
$bucket
[
'key'
],
'date'
=>
date
(
'c'
,
$bucket
[
'key'
]
/
1000
),
'value'
=>
$bucket
[
'2'
][
'value'
]
];
}
$this
->
visualisation
=
(
new
Visualisations\ChartVisualisation
())
->
setXLabel
(
'Date'
)
->
setYLabel
(
'Count'
)
->
setBuckets
(
$buckets
);
return
$this
;
}
}
Core/Analytics/Dashboards/Metrics/Earnings/ReferralsEarningsMetric.php
0 → 100644
View file @
cfaac31d
<?php
namespace
Minds\Core\Analytics\Dashboards\Metrics\Earnings
;
use
Minds\Core\Di\Di
;
use
Minds\Core\Session
;
use
Minds\Core\Data\ElasticSearch
;
use
Minds\Core\Analytics\Dashboards\Metrics\AbstractMetric
;
use
Minds\Core\Analytics\Dashboards\Metrics\MetricSummary
;
use
Minds\Core\Analytics\Dashboards\Metrics\Visualisations
;
class
ReferralsEarningsMetric
extends
AbstractEarningsMetric
{
/** @var string */
protected
$id
=
'earnings_referrals'
;
/** @var string */
protected
$label
=
'Referrals USD'
;
/** @var string */
protected
$description
=
'Referral earnings for PRO users'
;
/** @var array */
protected
$permissions
=
[
'user'
,
'admin'
];
/** @var string */
protected
$aggField
=
'usd_earnings::referrals'
;
}
Core/Analytics/Dashboards/Metrics/Earnings/SalesEarningsMetric.php
0 → 100644
View file @
cfaac31d
<?php
namespace
Minds\Core\Analytics\Dashboards\Metrics\Earnings
;
use
Minds\Core\Di\Di
;
use
Minds\Core\Session
;
use
Minds\Core\Data\ElasticSearch
;
use
Minds\Core\Analytics\Dashboards\Metrics\AbstractMetric
;
use
Minds\Core\Analytics\Dashboards\Metrics\MetricSummary
;
use
Minds\Core\Analytics\Dashboards\Metrics\Visualisations
;
class
SalesEarningsMetric
extends
AbstractEarningsMetric
{
/** @var string */
protected
$id
=
'earnings_sales'
;
/** @var string */
protected
$label
=
'Sales USD'
;
/** @var string */
protected
$description
=
'Sales earnings for PRO users'
;
/** @var array */
protected
$permissions
=
[
'user'
,
'admin'
];
/** @var string */
protected
$aggField
=
'usd_earnings::sales'
;
}
Core/Analytics/Dashboards/Metrics/Earnings/TotalEarningsMetric.php
0 → 100644
View file @
cfaac31d
<?php
namespace
Minds\Core\Analytics\Dashboards\Metrics\Earnings
;
use
Minds\Core\Di\Di
;
use
Minds\Core\Session
;
use
Minds\Core\Data\ElasticSearch
;
use
Minds\Core\Analytics\Dashboards\Metrics\AbstractMetric
;
use
Minds\Core\Analytics\Dashboards\Metrics\MetricSummary
;
use
Minds\Core\Analytics\Dashboards\Metrics\Visualisations
;
class
TotalEarningsMetric
extends
AbstractEarningsMetric
{
/** @var string */
protected
$id
=
'earnings_total'
;
/** @var string */
protected
$label
=
'Total Earnings'
;
/** @var string */
protected
$description
=
'Total earnings for PRO users'
;
/** @var array */
protected
$permissions
=
[
'user'
,
'admin'
];
/** @var string */
protected
$aggField
=
'usd_earnings::total'
;
}
Core/Analytics/Dashboards/Metrics/Earnings/ViewsEarningsMetric.php
0 → 100644
View file @
cfaac31d
<?php
namespace
Minds\Core\Analytics\Dashboards\Metrics\Earnings
;
use
Minds\Core\Di\Di
;
use
Minds\Core\Session
;
use
Minds\Core\Data\ElasticSearch
;
use
Minds\Core\Analytics\Dashboards\Metrics\AbstractMetric
;
use
Minds\Core\Analytics\Dashboards\Metrics\MetricSummary
;
use
Minds\Core\Analytics\Dashboards\Metrics\Visualisations
;
class
ViewsEarningsMetric
extends
AbstractEarningsMetric
{
/** @var string */
protected
$id
=
'earnings_views'
;
/** @var string */
protected
$label
=
'Views USD'
;
/** @var string */
protected
$description
=
'Views earnings for PRO users'
;
/** @var array */
protected
$permissions
=
[
'user'
,
'admin'
];
/** @var string */
protected
$aggField
=
'usd_earnings::views'
;
}
Core/Analytics/Dashboards/Metrics/MetricsCollection.php
View file @
cfaac31d
...
@@ -70,6 +70,9 @@ class MetricsCollection implements DashboardCollectionInterface
...
@@ -70,6 +70,9 @@ class MetricsCollection implements DashboardCollectionInterface
*/
*/
public
function
getSelected
():
AbstractMetric
public
function
getSelected
():
AbstractMetric
{
{
if
(
!
isset
(
$this
->
metrics
[
$this
->
selectedId
]))
{
$this
->
selectedId
=
key
(
$this
->
metrics
);
}
return
$this
->
metrics
[
$this
->
selectedId
];
return
$this
->
metrics
[
$this
->
selectedId
];
}
}
...
...
Core/Analytics/Dashboards/Metrics/SignupsMetric.php
View file @
cfaac31d
...
@@ -32,6 +32,10 @@ class SignupsMetric extends AbstractMetric
...
@@ -32,6 +32,10 @@ class SignupsMetric extends AbstractMetric
*/
*/
public
function
buildSummary
():
self
public
function
buildSummary
():
self
{
{
if
(
$this
->
getUserGuid
())
{
return
$this
;
}
$timespan
=
$this
->
timespansCollection
->
getSelected
();
$timespan
=
$this
->
timespansCollection
->
getSelected
();
$comparisonTsMs
=
strtotime
(
"-
{
$timespan
->
getComparisonInterval
()
}
days"
,
$timespan
->
getFromTsMs
()
/
1000
)
*
1000
;
$comparisonTsMs
=
strtotime
(
"-
{
$timespan
->
getComparisonInterval
()
}
days"
,
$timespan
->
getFromTsMs
()
/
1000
)
*
1000
;
$currentTsMs
=
$timespan
->
getFromTsMs
();
$currentTsMs
=
$timespan
->
getFromTsMs
();
...
@@ -95,6 +99,11 @@ class SignupsMetric extends AbstractMetric
...
@@ -95,6 +99,11 @@ class SignupsMetric extends AbstractMetric
*/
*/
public
function
buildVisualisation
():
self
public
function
buildVisualisation
():
self
{
{
if
(
$this
->
getUserGuid
())
{
$this
->
visualisation
=
(
new
Visualisations\ChartVisualisation
());
return
$this
;
}
$timespan
=
$this
->
timespansCollection
->
getSelected
();
$timespan
=
$this
->
timespansCollection
->
getSelected
();
$xValues
=
[];
$xValues
=
[];
$yValues
=
[];
$yValues
=
[];
...
...
Core/Analytics/Dashboards/Metrics/ViewsMetric.php
View file @
cfaac31d
...
@@ -3,7 +3,7 @@ namespace Minds\Core\Analytics\Dashboards\Metrics;
...
@@ -3,7 +3,7 @@ namespace Minds\Core\Analytics\Dashboards\Metrics;
use
Minds\Core\Di\Di
;
use
Minds\Core\Di\Di
;
use
Minds\Core\Session
;
use
Minds\Core\Session
;
use
Minds\Core\Data\Elastic
s
earch
;
use
Minds\Core\Data\Elastic
S
earch
;
class
ViewsMetric
extends
AbstractMetric
class
ViewsMetric
extends
AbstractMetric
{
{
...
@@ -48,14 +48,7 @@ class ViewsMetric extends AbstractMetric
...
@@ -48,14 +48,7 @@ class ViewsMetric extends AbstractMetric
$values
=
[];
$values
=
[];
foreach
([
'value'
=>
$currentTsMs
,
'comparison'
=>
$comparisonTsMs
]
as
$key
=>
$tsMs
)
{
foreach
([
'value'
=>
$currentTsMs
,
'comparison'
=>
$comparisonTsMs
]
as
$key
=>
$tsMs
)
{
$must
=
[];
$must
=
[];
// Specify the resolution to avoid duplicates
$must
[]
=
[
'term'
=>
[
'resolution'
=>
$timespan
->
getInterval
(),
],
];
$must
[][
'range'
]
=
[
$must
[][
'range'
]
=
[
'@timestamp'
=>
[
'@timestamp'
=>
[
'gte'
=>
$tsMs
,
'gte'
=>
$tsMs
,
...
@@ -133,13 +126,6 @@ class ViewsMetric extends AbstractMetric
...
@@ -133,13 +126,6 @@ class ViewsMetric extends AbstractMetric
],
],
];
];
// Specify the resolution to avoid duplicates
$must
[]
=
[
'term'
=>
[
'resolution'
=>
$timespan
->
getInterval
(),
],
];
if
(
$userGuid
=
$this
->
getUserGuid
())
{
if
(
$userGuid
=
$this
->
getUserGuid
())
{
$must
[]
=
[
$must
[]
=
[
'term'
=>
[
'term'
=>
[
...
@@ -203,24 +189,4 @@ class ViewsMetric extends AbstractMetric
...
@@ -203,24 +189,4 @@ class ViewsMetric extends AbstractMetric
return
$this
;
return
$this
;
}
}
private
function
getUserGuid
():
?string
{
$filters
=
$this
->
filtersCollection
->
getSelected
();
$channelFilter
=
$filters
[
'channel'
];
if
(
!
$channelFilter
)
{
return
""
;
}
if
(
$channelFilter
->
getSelectedOption
()
===
'self'
)
{
return
Session
::
getLoggedInUserGuid
();
}
if
(
$channelFilter
->
getSelectedOption
()
===
'all'
)
{
return
""
;
}
// TODO: check permissions first
return
$channelFilter
->
getSelectedOption
();
}
}
}
Core/Analytics/Dashboards/Metrics/ViewsTableMetric.php
View file @
cfaac31d
...
@@ -2,14 +2,18 @@
...
@@ -2,14 +2,18 @@
namespace
Minds\Core\Analytics\Dashboards\Metrics
;
namespace
Minds\Core\Analytics\Dashboards\Metrics
;
use
Minds\Core\Di\Di
;
use
Minds\Core\Di\Di
;
use
Minds\Core\Session
;
use
Minds\Core\Data\ElasticSearch
;
use
Minds\Core\Data\ElasticSearch
;
use
Minds\Core\Entities\Resolver
;
use
Minds\Common\Urn
;
class
ViewsTableMetric
extends
AbstractMetric
class
ViewsTableMetric
extends
AbstractMetric
{
{
/** @var Elasticsearch\Client */
/** @var Elasticsearch\Client */
private
$es
;
private
$es
;
/** @var Resolver */
private
$entitiesResolver
;
/** @var string */
/** @var string */
protected
$id
=
'views_table'
;
protected
$id
=
'views_table'
;
...
@@ -25,6 +29,7 @@ class ViewsTableMetric extends AbstractMetric
...
@@ -25,6 +29,7 @@ class ViewsTableMetric extends AbstractMetric
public
function
__construct
(
$es
=
null
)
public
function
__construct
(
$es
=
null
)
{
{
$this
->
es
=
$es
??
Di
::
_
()
->
get
(
'Database\ElasticSearch'
);
$this
->
es
=
$es
??
Di
::
_
()
->
get
(
'Database\ElasticSearch'
);
$this
->
entitiesResolver
=
$entitiesResolver
??
new
Resolver
();
}
}
/**
/**
...
@@ -67,11 +72,11 @@ class ViewsTableMetric extends AbstractMetric
...
@@ -67,11 +72,11 @@ class ViewsTableMetric extends AbstractMetric
];
];
// Specify the resolution to avoid duplicates
// Specify the resolution to avoid duplicates
$must
[]
=
[
//
$must[] = [
'term'
=>
[
//
'term' => [
'resolution'
=>
$timespan
->
getInterval
(),
//
'resolution' => $timespan->getInterval(),
],
//
],
];
//
];
if
(
$userGuid
=
$this
->
getUserGuid
())
{
if
(
$userGuid
=
$this
->
getUserGuid
())
{
$must
[]
=
[
$must
[]
=
[
...
@@ -107,10 +112,10 @@ class ViewsTableMetric extends AbstractMetric
...
@@ -107,10 +112,10 @@ class ViewsTableMetric extends AbstractMetric
],
],
],
],
'views::organic'
=>
[
'views::organic'
=>
[
'sum'
=>
[
'sum'
=>
[
'field'
=>
'views::organic'
,
'field'
=>
'views::organic'
,
],
],
],
],
'views::single'
=>
[
'views::single'
=>
[
'sum'
=>
[
'sum'
=>
[
'field'
=>
'views::single'
,
'field'
=>
'views::single'
,
...
@@ -126,45 +131,47 @@ class ViewsTableMetric extends AbstractMetric
...
@@ -126,45 +131,47 @@ class ViewsTableMetric extends AbstractMetric
$prepared
=
new
ElasticSearch\Prepared\Search
();
$prepared
=
new
ElasticSearch\Prepared\Search
();
$prepared
->
query
(
$query
);
$prepared
->
query
(
$query
);
$response
=
$this
->
es
->
request
(
$prepared
);
$response
=
$this
->
es
->
request
(
$prepared
);
$buckets
=
[];
$buckets
=
[];
foreach
(
$response
[
'aggregations'
][
'1'
][
'buckets'
]
as
$bucket
)
{
foreach
(
$response
[
'aggregations'
][
'1'
][
'buckets'
]
as
$bucket
)
{
$date
=
date
(
Visualisations\ChartVisualisation
::
DATE_FORMAT
,
$bucket
[
'key'
]
/
1000
);
$date
=
date
(
Visualisations\ChartVisualisation
::
DATE_FORMAT
,
$bucket
[
'key'
]
/
1000
);
$
subBuckets
=
[]
;
$
entity
=
$this
->
entitiesResolver
->
single
(
new
Urn
(
$bucket
[
'key'
]))
;
$buckets
[]
=
[
$buckets
[]
=
[
'key'
=>
$bucket
[
'key'
],
'key'
=>
$bucket
[
'key'
],
'values'
=>
[
'values'
=>
[
'views::total'
=>
$bucket
[
'views::total'
][
'value'
],
'entity'
=>
$entity
?
$entity
->
export
()
:
null
,
'views::organic'
=>
$bucket
[
'views::organic'
][
'value'
],
'views::total'
=>
$bucket
[
'views::total'
][
'value'
],
'views::single'
=>
$bucket
[
'views::single'
][
'value'
],
'views::organic'
=>
$bucket
[
'views::organic'
][
'value'
],
],
'views::single'
=>
$bucket
[
'views::single'
][
'value'
],
],
];
];
}
}
$this
->
visualisation
=
(
new
Visualisations\TableVisualisation
())
$this
->
visualisation
=
(
new
Visualisations\TableVisualisation
())
->
setBuckets
(
$buckets
)
->
setBuckets
(
$buckets
)
->
setColumns
([
'views::total'
,
'views::organic'
,
'views::single'
]);
->
setColumns
([
[
'id'
=>
'entity'
,
'label'
=>
''
,
'order'
=>
0
,
],
[
'id'
=>
'views::total'
,
'label'
=>
'Total Views'
,
'order'
=>
1
,
],
[
'id'
=>
'views::organic'
,
'label'
=>
'Organic'
,
'order'
=>
2
,
],
[
'id'
=>
'views::single'
,
'label'
=>
'Single'
,
'order'
=>
3
,
]
]);
return
$this
;
return
$this
;
}
}
private
function
getUserGuid
():
?string
{
$filters
=
$this
->
filtersCollection
->
getSelected
();
$channelFilter
=
$filters
[
'channel'
];
if
(
!
$channelFilter
)
{
return
""
;
}
if
(
$channelFilter
->
getSelectedOption
()
===
'self'
)
{
return
Session
::
getLoggedInUserGuid
();
}
if
(
$channelFilter
->
getSelectedOption
()
===
'all'
)
{
return
""
;
}
// TODO: check permissions first
return
$channelFilter
->
getSelectedOption
();
}
}
}
Core/Analytics/Dashboards/TrafficDashboard.php
View file @
cfaac31d
...
@@ -63,7 +63,7 @@ class TrafficDashboard implements DashboardInterface
...
@@ -63,7 +63,7 @@ class TrafficDashboard implements DashboardInterface
$this
->
filtersCollection
$this
->
filtersCollection
->
setSelectedIds
(
$this
->
filterIds
)
->
setSelectedIds
(
$this
->
filterIds
)
->
addFilters
(
->
addFilters
(
new
Filters\PlatformFilter
(),
//
new Filters\PlatformFilter(),
new
Filters\ViewTypeFilter
(),
new
Filters\ViewTypeFilter
(),
new
Filters\ChannelFilter
()
new
Filters\ChannelFilter
()
);
);
...
...
Core/Analytics/Dashboards/TrendingDashboard.php
View file @
cfaac31d
...
@@ -60,7 +60,7 @@ class TrendingDashboard implements DashboardInterface
...
@@ -60,7 +60,7 @@ class TrendingDashboard implements DashboardInterface
$this
->
filtersCollection
$this
->
filtersCollection
->
setSelectedIds
(
$this
->
filterIds
)
->
setSelectedIds
(
$this
->
filterIds
)
->
addFilters
(
->
addFilters
(
new
Filters\PlatformFilter
(),
//
new Filters\PlatformFilter(),
new
Filters\ViewTypeFilter
(),
new
Filters\ViewTypeFilter
(),
new
Filters\ChannelFilter
()
new
Filters\ChannelFilter
()
);
);
...
...
Core/Analytics/EntityCentric/EntityCentricRecord.php
View file @
cfaac31d
...
@@ -60,4 +60,12 @@ class EntityCentricRecord
...
@@ -60,4 +60,12 @@ class EntityCentricRecord
$this
->
sums
[
$metric
]
=
$this
->
sums
[
$metric
]
+
$value
;
$this
->
sums
[
$metric
]
=
$this
->
sums
[
$metric
]
+
$value
;
return
$this
;
return
$this
;
}
}
/**
* @return string
*/
public
function
getUrn
():
string
{
return
(
string
)
implode
(
'-'
,
[
$this
->
getEntityUrn
(),
$this
->
getResolution
(),
$this
->
getTimestamp
()
]);
}
}
}
Core/Analytics/EntityCentric/Manager.php
View file @
cfaac31d
...
@@ -13,6 +13,7 @@ class Manager
...
@@ -13,6 +13,7 @@ class Manager
{
{
/** @var array */
/** @var array */
const
SYNCHRONISERS
=
[
const
SYNCHRONISERS
=
[
PartnerEarningsSynchroniser
::
class
,
SignupsSynchroniser
::
class
,
SignupsSynchroniser
::
class
,
ActiveUsersSynchroniser
::
class
,
ActiveUsersSynchroniser
::
class
,
ViewsSynchroniser
::
class
,
ViewsSynchroniser
::
class
,
...
@@ -21,6 +22,9 @@ class Manager
...
@@ -21,6 +22,9 @@ class Manager
/** @var Repository */
/** @var Repository */
protected
$repository
;
protected
$repository
;
/** @var Sums */
protected
$sums
;
/** @var int */
/** @var int */
private
$from
;
private
$from
;
...
@@ -28,9 +32,11 @@ class Manager
...
@@ -28,9 +32,11 @@ class Manager
private
$to
;
private
$to
;
public
function
__construct
(
public
function
__construct
(
$repository
=
null
$repository
=
null
,
$sums
=
null
)
{
)
{
$this
->
repository
=
$repository
?:
new
Repository
();
$this
->
repository
=
$repository
??
new
Repository
();
$this
->
sums
=
$sums
??
new
Sums
();
}
}
/**
/**
...
@@ -81,4 +87,13 @@ class Manager
...
@@ -81,4 +87,13 @@ class Manager
public
function
getAggregateByQuery
(
array
$query
):
array
public
function
getAggregateByQuery
(
array
$query
):
array
{
{
}
}
/**
* @param array $opts
* @retun iterable
*/
public
function
getListAggregatedByOwner
(
array
$opts
=
[]):
iterable
{
return
$this
->
sums
->
getByOwner
(
$opts
);
}
}
}
Core/Analytics/EntityCentric/PartnerEarningsSynchroniser.php
0 → 100644
View file @
cfaac31d
<?php
namespace
Minds\Core\Analytics\EntityCentric
;
use
Minds\Core\Monetization\Partners\Manager
as
PartnersManager
;
use
DateTime
;
use
Exception
;
class
PartnerEarningsSynchroniser
{
/** @var PartnersManager */
private
$partnersManager
;
public
function
__construct
(
$partnersManager
=
null
)
{
$this
->
partnersManager
=
$partnersManager
??
new
PartnersManager
;
}
/**
* @param int $from
* @return self
*/
public
function
setFrom
(
$from
):
self
{
$this
->
from
=
$from
;
return
$this
;
}
/**
* Convert to records
* @return iterable
*/
public
function
toRecords
():
iterable
{
$opts
=
[];
$opts
[
'from'
]
=
$this
->
from
;
$records
=
[];
$i
=
0
;
while
(
true
)
{
$result
=
$this
->
partnersManager
->
getList
(
$opts
);
$opts
[
'offset'
]
=
$result
->
getPagingToken
();
foreach
(
$result
as
$deposit
)
{
$urn
=
"urn:user:
{
$deposit
->
getUserGuid
()
}
"
;
$record
=
new
EntityCentricRecord
();
$record
->
setEntityUrn
(
$urn
)
->
setOwnerGuid
(
$deposit
->
getUserGuid
())
->
setTimestamp
(
$deposit
->
getTimestamp
())
// TODO: confirm if this should be rounded to midnight
->
setResolution
(
'day'
);
// In order to increment sums, replace with what has already been seen
if
(
isset
(
$records
[
$record
->
getUrn
()]))
{
$record
=
$records
[
$record
->
getUrn
()];
}
$record
->
incrementSum
(
'usd_earnings::total'
,
$deposit
->
getAmountCents
());
$record
->
incrementSum
(
"usd_earnings::
{
$deposit
->
getItem
()
}
"
,
$deposit
->
getAmountCents
());
$records
[
$record
->
getUrn
()]
=
$record
;
}
if
(
$result
->
isLastPage
())
{
break
;
}
}
foreach
(
$records
as
$record
)
{
var_dump
(
$record
);
yield
$record
;
}
}
}
Core/Analytics/EntityCentric/Sums.php
0 → 100644
View file @
cfaac31d
<?php
/**
* EntityCentric Sums
* @author Mark
*/
namespace
Minds\Core\Analytics\EntityCentric
;
use
DateTime
;
use
DateTimeZone
;
use
Exception
;
use
Minds\Common\Repository\Response
;
use
Minds\Core\Data\ElasticSearch\Client
as
ElasticClient
;
use
Minds\Core\Data\ElasticSearch
;
use
Minds\Core\Di\Di
;
class
Sums
{
/** @var ElasticClient */
protected
$es
;
/**
* Repository constructor.
* @param ElasticClient $es
*/
public
function
__construct
(
$es
=
null
)
{
$this
->
es
=
$es
?:
Di
::
_
()
->
get
(
'Database\ElasticSearch'
);
}
public
function
getByOwner
(
array
$opts
=
[]):
iterable
{
$opts
=
array_merge
([
'fields'
=>
[],
'from'
=>
time
(),
],
$opts
);
$must
=
[];
$must
[]
=
[
'range'
=>
[
'@timestamp'
=>
[
'gte'
=>
$opts
[
'from'
]
*
1000
,
'lt'
=>
strtotime
(
'+1 day'
,
$opts
[
'from'
])
*
1000
,
],
],
];
$termsAgg
=
[];
foreach
(
$opts
[
'fields'
]
as
$field
)
{
$termsAgg
[
$field
]
=
[
'sum'
=>
[
'field'
=>
$field
,
],
];
$must
[]
=
[
'exists'
=>
[
'field'
=>
$field
,
],
];
}
$partition
=
0
;
$partitions
=
100
;
$partitionSize
=
5000
;
// Allows for 500,000 users
while
(
++
$partition
<
$partitions
)
{
// Do the query
$query
=
[
'index'
=>
'minds-entitycentric-*'
,
'size'
=>
0
,
'body'
=>
[
'query'
=>
[
'bool'
=>
[
'must'
=>
$must
,
],
],
'aggs'
=>
[
'1'
=>
[
'terms'
=>
[
'field'
=>
'owner_guid'
,
'min_doc_count'
=>
1
,
'size'
=>
$partitionSize
,
'include'
=>
[
'partition'
=>
$partition
,
'num_partitions'
=>
$partitions
,
],
],
'aggs'
=>
$termsAgg
,
],
],
],
];
// Query elasticsearch
$prepared
=
new
ElasticSearch\Prepared\Search
();
$prepared
->
query
(
$query
);
$response
=
$this
->
es
->
request
(
$prepared
);
foreach
(
$response
[
'aggregations'
][
'1'
][
'buckets'
]
as
$bucket
)
{
yield
$bucket
;
}
}
}
}
Prev
1
2
Next