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
134
Issues
134
List
Boards
Labels
Service Desk
Milestones
Merge Requests
28
Merge Requests
28
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
a4b616fffd83c4d25f4a15b06410085d25d665d3...ca945dffc77b77789a027ac0ac2d14c72ef41e5a
Source
ca945dffc77b77789a027ac0ac2d14c72ef41e5a
Select Git revision
...
Target
a4b616fffd83c4d25f4a15b06410085d25d665d3
Select Git revision
Compare
Commits (2)
Moderation summons queue
· 93e375c0
Emiliano Balbuena
authored
7 hours ago
93e375c0
Merge branch 'goal/ReportingAndModeration.summons-queue' into 'epic/ReportingAndModeration'
· ca945dff
Mark Harding
authored
7 hours ago
Moderation summons queue See merge request
!166
ca945dff
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
583 additions
and
161 deletions
+583
-161
Moderation.php
Controllers/Cli/Moderation.php
+63
-3
summons.php
Controllers/api/v2/moderation/summons.php
+2
-9
ReportsAppealSummon.php
Core/Queue/Runners/ReportsAppealSummon.php
+14
-1
Cohort.php
Core/Reports/Summons/Cohort.php
+58
-116
SocketDelegate.php
Core/Reports/Summons/Delegates/SocketDelegate.php
+2
-1
Manager.php
Core/Reports/Summons/Manager.php
+87
-11
Pool.php
Core/Reports/Summons/Pool.php
+167
-0
Repository.php
Core/Reports/Summons/Repository.php
+116
-6
Summon.php
Core/Reports/Summons/Summon.php
+5
-3
ReleaseSummonsesDelegate.php
Core/Reports/Verdict/Delegates/ReleaseSummonsesDelegate.php
+43
-0
Manager.php
Core/Reports/Verdict/Manager.php
+10
-1
Verdict.php
Core/Reports/Verdict/Verdict.php
+8
-8
ManagerSpec.php
Spec/Core/Reports/Verdict/ManagerSpec.php
+8
-2
No files found.
Controllers/Cli/Moderation.php
View file @
ca945dff
...
...
@@ -5,6 +5,7 @@ namespace Minds\Controllers\Cli;
use
Minds\Core
;
use
Minds\Core\Di\Di
;
use
Minds\Cli
;
use
Minds\Core\Reports\Summons\Summon
;
use
Minds\Interfaces
;
use
Minds\Entities
;
...
...
@@ -47,9 +48,16 @@ class Moderation extends Cli\Controller implements Interfaces\CliControllerInter
$userId
=
$this
->
getOpt
(
'user'
);
$reportUrn
=
$this
->
getOpt
(
'report'
);
$juryType
=
$this
->
getOpt
(
'jury-type'
)
??
null
;
$respond
=
$this
->
getOpt
(
'respond'
)
??
null
;
if
(
!
$userId
||
!
$reportUrn
)
{
$this
->
out
(
'Usage: cli.php moderation summon --user=<username_or_guid> --report=<report_urn>'
);
$this
->
out
([
'Usage:'
,
'- Summoning: cli.php moderation summon --user=<username_or_guid> --report=<report_urn>'
,
'- Responding: cli.php moderation summon --user=<username_or_guid> --report=<report_urn> --jury-type=<initial_jury|appeal_jury> --respond=<accepted|declined>'
,
]);
exit
(
1
);
}
...
...
@@ -60,6 +68,54 @@ class Moderation extends Cli\Controller implements Interfaces\CliControllerInter
exit
(
1
);
}
if
(
!
$respond
)
{
$report
=
$reportsRepository
->
get
(
$reportUrn
);
if
(
!
$report
)
{
$this
->
out
(
'Error: Invalid report'
);
exit
(
1
);
}
$appeal
=
new
Core\Reports\Appeals\Appeal
();
$appeal
->
setReport
(
$report
);
$summonsManager
->
summon
(
$appeal
,
[
$user
->
guid
]);
$this
->
out
(
"Summoned
{
$user
->
guid
}
to
{
$reportUrn
}
"
);
}
else
{
$summon
=
new
Summon
();
$summon
->
setReportUrn
(
$reportUrn
)
->
setJuryType
(
$juryType
)
->
setJurorGuid
((
string
)
$user
->
guid
)
->
setStatus
(
$respond
);
$summonsManager
->
respond
(
$summon
);
$this
->
out
(
"Responded to
{
$user
->
guid
}
's summon to
{
$reportUrn
}
with
{
$respond
}
"
);
}
}
public
function
dev_only_simulate_summon
()
{
error_reporting
(
E_ALL
);
ini_set
(
'display_errors'
,
1
);
/** @var Core\Reports\Repository $reportsRepository */
$reportsRepository
=
Di
::
_
()
->
get
(
'Reports\Repository'
);
/** @var Core\Reports\Summons\Manager $summonsManager */
$summonsManager
=
Di
::
_
()
->
get
(
'Moderation\Summons\Manager'
);
$reportUrn
=
$this
->
getOpt
(
'report'
);
if
(
!
$reportUrn
)
{
$this
->
out
([
'Usage: cli.php moderation dev_only_simulate_summon --report=<report_urn>'
,
]);
exit
(
1
);
}
$report
=
$reportsRepository
->
get
(
$reportUrn
);
if
(
!
$report
)
{
...
...
@@ -68,8 +124,12 @@ class Moderation extends Cli\Controller implements Interfaces\CliControllerInter
}
$appeal
=
new
Core\Reports\Appeals\Appeal
();
$appeal
->
setReport
(
$report
);
$appeal
->
setReport
(
$report
)
->
setOwnerGuid
(
$report
->
getEntityOwnerGuid
());
$cohort
=
$summonsManager
->
summon
(
$appeal
,
null
);
$summonsManager
->
summon
(
$appeal
,
[
$user
->
guid
]
);
var_dump
(
$cohort
);
}
}
This diff is collapsed.
Click to expand it.
Controllers/api/v2/moderation/summons.php
View file @
ca945dff
...
...
@@ -53,6 +53,8 @@ class summons implements Interfaces\Api
->
setJuryType
(
$juryType
)
->
setJurorGuid
((
string
)
$userGuid
)
->
setStatus
(
$status
);
$summonsManager
->
respond
(
$summon
);
}
catch
(
\Exception
$e
)
{
return
Factory
::
response
([
'status'
=>
'error'
,
...
...
@@ -60,15 +62,6 @@ class summons implements Interfaces\Api
]);
}
if
(
!
$summonsManager
->
isSummoned
(
$summon
))
{
return
Factory
::
response
([
'status'
=>
'error'
,
'message'
=>
'You\'re not summoned'
,
]);
}
$summonsManager
->
respond
(
$summon
);
$response
=
[
'summon'
=>
$summon
->
getStatus
(),
'expires_in'
=>
$summon
->
getTtl
(),
...
...
This diff is collapsed.
Click to expand it.
Core/Queue/Runners/ReportsAppealSummon.php
View file @
ca945dff
...
...
@@ -12,6 +12,7 @@ use Minds\Core\Queue\Message;
use
Minds\Core\Queue\Client
;
use
Minds\Core\Queue\Interfaces\QueueClient
;
use
Minds\Core\Queue\Interfaces\QueueRunner
;
use
Minds\Core\Reports\Appeals\Appeal
;
use
Minds\Core\Reports\Summons\Manager
;
class
ReportsAppealSummon
implements
QueueRunner
...
...
@@ -31,7 +32,10 @@ class ReportsAppealSummon implements QueueRunner
->
receive
(
function
(
Message
$data
)
{
$params
=
$data
->
getData
();
/** @var Appeal $appeal */
$appeal
=
$params
[
'appeal'
]
??
null
;
/** @var string[] $cohort */
$cohort
=
$params
[
'cohort'
]
??
null
;
if
(
!
$appeal
)
{
...
...
@@ -39,9 +43,18 @@ class ReportsAppealSummon implements QueueRunner
return
;
}
echo
"Summoning for
{
$appeal
->
getReport
()
->
getUrn
()
}
..."
.
PHP_EOL
;
/** @var Manager $manager */
$manager
=
Di
::
_
()
->
get
(
'Moderation\Summons\Manager'
);
$manager
->
summon
(
$appeal
,
$cohort
);
$missing
=
$manager
->
summon
(
$appeal
,
$cohort
);
if
(
$missing
>
0
)
{
echo
"Missing
{
$missing
}
juror(s). Deferring..."
.
PHP_EOL
;
$manager
->
defer
(
$appeal
);
}
echo
"Done!"
.
PHP_EOL
;
});
}
}
This diff is collapsed.
Click to expand it.
Core/Reports/Summons/Cohort.php
View file @
ca945dff
...
...
@@ -7,149 +7,91 @@
namespace
Minds\Core\Reports\Summons
;
use
Minds\Core\Data\ElasticSearch\Client
as
ElasticsearchClient
;
use
Minds\Core\Data\ElasticSearch\Prepared\Search
;
use
Minds\Core\Di\Di
;
use
Minds\Helpers\Text
;
use
Exception
;
class
Cohort
{
/** @var
ElasticsearchClient
*/
protected
$
elasticsearch
;
/** @var
Repository
*/
protected
$
repository
;
/** @var
string
*/
protected
$
index
;
/** @var
Pool
*/
protected
$
pool
;
/**
*
Repository
constructor.
* @param
ElasticsearchClient $elasticsearch
* @param
string $index
*
Cohort
constructor.
* @param
Repository $repository
* @param
Pool $pool
*/
public
function
__construct
(
$
elasticsearch
=
null
,
$
index
=
null
$
repository
=
null
,
$
pool
=
null
)
{
$this
->
elasticsearch
=
$elasticsearch
?:
Di
::
_
()
->
get
(
'Database\ElasticSearch'
);
$this
->
index
=
$index
?:
'minds-metrics-*'
;
$this
->
repository
=
$repository
?:
new
Repository
(
);
$this
->
pool
=
$pool
?:
new
Pool
()
;
}
/**
* @param array $opts
* @return
\Generator
* @
yields string
* @return
string[]
* @
throws Exception
*/
public
function
getList
(
array
$opts
=
[]
)
public
function
pick
(
$opts
)
{
$opts
=
array_merge
([
'size'
=>
0
,
'for'
=>
null
,
'active_threshold'
=>
0
,
'platform'
=>
null
,
'validated'
=>
false
,
'limit'
=>
10
,
'offset'
=>
0
,
'except'
=>
[],
'active_threshold'
=>
null
,
],
$opts
);
$now
=
(
int
)
(
microtime
(
true
)
*
1000
);
$fromTimestamp
=
$now
-
(
$opts
[
'active_threshold'
]
*
1000
);
$body
=
[
'_source'
=>
[
'user_guid'
,
],
'query'
=>
[
'bool'
=>
[
'must'
=>
[
[
'range'
=>
[
'@timestamp'
=>
[
'gte'
=>
$fromTimestamp
,
],
],
],
[
'term'
=>
[
'type'
=>
'action'
,
],
],
],
],
],
'aggs'
=>
[
'entities'
=>
[
'terms'
=>
[
'field'
=>
'user_guid.keyword'
,
'size'
=>
$opts
[
'limit'
],
],
],
],
'size'
=>
0
,
];
if
(
$opts
[
'platform'
])
{
$body
[
'query'
][
'bool'
][
'must'
][]
=
[
'terms'
=>
[
'platform'
=>
Text
::
buildArray
(
$opts
[
'platform'
]),
],
];
}
if
(
$opts
[
'for'
])
{
if
(
!
isset
(
$body
[
'query'
][
'bool'
][
'must_not'
]))
{
$body
[
'query'
][
'bool'
][
'must_not'
]
=
[];
}
$cohort
=
[];
$body
[
'query'
][
'bool'
][
'must_not'
][]
=
[
'term'
=>
[
'user_guid'
=>
(
string
)
$opts
[
'for'
],
],
];
$body
[
'query'
][
'bool'
][
'must_not'
][]
=
[
'terms'
=>
[
'user_guid'
=>
[
'index'
=>
'minds-graph'
,
'type'
=>
'subscriptions'
,
'id'
=>
(
string
)
$opts
[
'for'
],
'path'
=>
'guids'
,
],
],
];
}
// Uncomment below to scale
// $poolSize = $opts['size'] * 5;
// $max_pages = 20; // NOTE: Normally capped to 20.
if
(
$opts
[
'validated'
])
{
$body
[
'query'
][
'bool'
][
'must'
][]
=
[
'exists'
=>
[
'field'
=>
'user_phone_number_hash'
,
],
];
$poolSize
=
400
;
$max_pages
=
1
;
// NOTE: Normally capped to 20.
$page
=
0
;
if
(
!
isset
(
$body
[
'query'
][
'bool'
][
'must_not'
]))
{
$body
[
'query'
][
'bool'
][
'must_not'
]
=
[];
while
(
true
)
{
if
(
$page
>
$max_pages
)
{
// Max = PoolSize * MaxPages
error_log
(
'Cannot gather a cohort'
);
break
;
}
$body
[
'query'
][
'bool'
][
'must_not'
][]
=
[
'term'
=>
[
'user_phone_number_hash'
=>
''
,
],
];
}
$query
=
[
'index'
=>
$this
->
index
,
'type'
=>
'action'
,
'body'
=>
$body
,
'size'
=>
$opts
[
'limit'
],
'from'
=>
$opts
[
'offset'
],
];
$prepared
=
new
Search
();
$prepared
->
query
(
$query
);
$pool
=
$this
->
pool
->
getList
([
'active_threshold'
=>
$opts
[
'active_threshold'
],
'platform'
=>
'browser'
,
'for'
=>
$opts
[
'for'
],
'except'
=>
$opts
[
'except'
],
'validated'
=>
false
,
'size'
=>
$poolSize
,
'page'
=>
$page
,
'max_pages'
=>
$max_pages
,
]);
$j
=
0
;
foreach
(
$pool
as
$userGuid
)
{
$j
++
;
// TODO: Check subs
$cohort
[]
=
$userGuid
;
if
(
count
(
$cohort
)
>=
$opts
[
'size'
])
{
break
;
}
}
$result
=
$this
->
elasticsearch
->
request
(
$prepared
);
if
(
$j
===
0
||
count
(
$cohort
)
>=
$opts
[
'size'
])
{
break
;
}
foreach
(
$result
[
'aggregations'
][
'entities'
][
'buckets'
]
as
$bucket
)
{
yield
$bucket
[
'key'
];
$page
++
;
}
return
$cohort
;
}
}
This diff is collapsed.
Click to expand it.
Core/Reports/Summons/Delegates/SocketDelegate.php
View file @
ca945dff
...
...
@@ -7,6 +7,7 @@
namespace
Minds\Core\Reports\Summons\Delegates
;
use
Exception
;
use
Minds\Core\Reports\Summons\Summon
;
use
Minds\Core\Sockets\Events
as
SocketEvents
;
...
...
@@ -28,7 +29,7 @@ class SocketDelegate
/**
* @param Summon $summon
* @throws
\
Exception
* @throws Exception
*/
public
function
onSummon
(
Summon
$summon
)
{
...
...
This diff is collapsed.
Click to expand it.
Core/Reports/Summons/Manager.php
View file @
ca945dff
...
...
@@ -7,6 +7,10 @@
namespace
Minds\Core\Reports\Summons
;
use
Exception
;
use
Minds\Core\Queue\Client
as
QueueClient
;
use
Minds\Core\Queue\Client
;
use
Minds\Core\Queue\Runners\ReportsAppealSummon
;
use
Minds\Core\Reports\Appeals\Appeal
;
use
Minds\Core\Reports\Summons\Delegates
;
...
...
@@ -15,9 +19,12 @@ class Manager
/** @var Cohort $cohort */
protected
$cohort
;
/** @va
t
Repository $repository */
/** @va
r
Repository $repository */
protected
$repository
;
/** @var QueueClient */
protected
$queueClient
;
/** @var Delegates\SocketDelegate $socketDelegate */
protected
$socketDelegate
;
...
...
@@ -25,39 +32,75 @@ class Manager
* Manager constructor.
* @param Cohort $cohort
* @param Repository $repository
* @param QueueClient $queueClient
* @param Delegates\SocketDelegate $socketDelegate
* @throws Exception
*/
public
function
__construct
(
$cohort
=
null
,
$repository
=
null
,
$queueClient
=
null
,
$socketDelegate
=
null
)
{
$this
->
cohort
=
$cohort
?:
new
Cohort
();
$this
->
repository
=
$repository
?:
new
Repository
();
$this
->
queueClient
=
$queueClient
?:
Client
::
build
();
$this
->
socketDelegate
=
$socketDelegate
?:
new
Delegates\SocketDelegate
();
}
/**
* @param Appeal $appeal
* @param array $cohort
* @throws \Exception
* @return int
* @throws Exception
*/
public
function
summon
(
Appeal
$appeal
,
$cohort
=
null
)
{
$cohort
=
$cohort
?:
$this
->
cohort
->
getList
([
'active_threshold'
=>
5
*
60
,
'platform'
=>
'browser'
,
'for'
=>
$appeal
->
getOwnerGuid
(),
'validated'
=>
true
,
'limit'
=>
12
,
]);
$reportUrn
=
$appeal
->
getReport
()
->
getUrn
();
$juryType
=
'appeal_jury'
;
$missing
=
0
;
if
(
!
$cohort
)
{
$jury
=
iterator_to_array
(
$this
->
repository
->
getList
([
'report_urn'
=>
$reportUrn
,
'jury_type'
=>
$juryType
,
]));
// Check how many are missing
$notDeclined
=
array_filter
(
$jury
,
function
(
Summon
$summon
)
{
return
$summon
->
isAccepted
()
||
$summon
->
isAwaiting
();
});
$missing
=
12
-
count
(
$notDeclined
);
// If we have a full jury, don't summon
if
(
$missing
<=
0
)
{
return
0
;
}
// Reduce jury to juror guids and try to pick up to missing size
$juryGuids
=
array_map
(
function
(
Summon
$summon
)
{
return
(
string
)
$summon
->
getJurorGuid
();
},
$jury
);
$cohort
=
$this
->
cohort
->
pick
([
'size'
=>
$missing
,
'for'
=>
$appeal
->
getOwnerGuid
(),
'except'
=>
$juryGuids
,
'active_threshold'
=>
5
*
60
,
]);
}
foreach
(
$cohort
as
$juror
)
{
$summon
=
new
Summon
();
$summon
->
setReportUrn
(
$
appeal
->
getReport
()
->
getUrn
()
)
->
setJuryType
(
'appeal_jury'
)
->
setReportUrn
(
$
reportUrn
)
->
setJuryType
(
$juryType
)
->
setJurorGuid
(
$juror
)
->
setTtl
(
120
)
->
setStatus
(
'awaiting'
);
...
...
@@ -65,6 +108,8 @@ class Manager
$this
->
repository
->
add
(
$summon
);
$this
->
socketDelegate
->
onSummon
(
$summon
);
}
return
$missing
;
}
/**
...
...
@@ -79,9 +124,14 @@ class Manager
/**
* @param Summon $summon
* @return Summon
* @throws Exception
*/
public
function
respond
(
Summon
$summon
)
{
if
(
!
$this
->
isSummoned
(
$summon
))
{
throw
new
Exception
(
'User is not summoned'
);
}
$summon
->
setTtl
(
10
*
60
);
...
...
@@ -89,4 +139,30 @@ class Manager
return
$summon
;
}
/**
* @param string $reportUrn
* @param string $juryType
* @return bool
* @throws Exception
*/
public
function
release
(
$reportUrn
,
$juryType
)
{
return
$this
->
repository
->
deleteAll
([
'report_urn'
=>
$reportUrn
,
'jury_type'
=>
$juryType
,
]);
}
/**
* @param Appeal $appeal
*/
public
function
defer
(
Appeal
$appeal
)
{
$this
->
queueClient
->
setQueue
(
ReportsAppealSummon
::
class
)
->
send
([
'appeal'
=>
$appeal
,
],
600
);
}
}
This diff is collapsed.
Click to expand it.
Core/Reports/Summons/Pool.php
0 → 100644
View file @
ca945dff
<?php
/**
* User Pool for Cohort
*
* @author edgebal
*/
namespace
Minds\Core\Reports\Summons
;
use
Generator
;
use
Minds\Core\Data\ElasticSearch\Client
as
ElasticsearchClient
;
use
Minds\Core\Data\ElasticSearch\Prepared\Search
;
use
Minds\Core\Di\Di
;
use
Minds\Helpers\Text
;
class
Pool
{
/** @var ElasticsearchClient */
protected
$elasticsearch
;
/** @var string */
protected
$index
;
/**
* Repository constructor.
* @param ElasticsearchClient $elasticsearch
* @param string $index
*/
public
function
__construct
(
$elasticsearch
=
null
,
$index
=
null
)
{
$this
->
elasticsearch
=
$elasticsearch
?:
Di
::
_
()
->
get
(
'Database\ElasticSearch'
);
$this
->
index
=
$index
?:
'minds-metrics-*'
;
}
/**
* @param array $opts
* @return Generator
* @yields string
*/
public
function
getList
(
array
$opts
=
[])
{
$opts
=
array_merge
([
'for'
=>
null
,
'active_threshold'
=>
0
,
'platform'
=>
null
,
'validated'
=>
false
,
'size'
=>
10
,
'page'
=>
0
,
'max_pages'
=>
20
,
],
$opts
);
$now
=
(
int
)
(
microtime
(
true
)
*
1000
);
$fromTimestamp
=
$now
-
(
$opts
[
'active_threshold'
]
*
1000
);
$body
=
[
'_source'
=>
[
'user_guid'
,
],
'query'
=>
[
'bool'
=>
[
'must'
=>
[
[
'range'
=>
[
'@timestamp'
=>
[
'gte'
=>
$fromTimestamp
,
],
],
],
[
'term'
=>
[
'type'
=>
'action'
,
],
],
],
],
],
'aggs'
=>
[
'entities'
=>
[
'terms'
=>
[
'field'
=>
'user_guid.keyword'
,
'size'
=>
$opts
[
'size'
],
'include'
=>
[
'partition'
=>
$opts
[
'page'
],
'num_partitions'
=>
$opts
[
'max_pages'
],
],
],
],
],
'size'
=>
0
,
];
if
(
$opts
[
'platform'
])
{
$body
[
'query'
][
'bool'
][
'must'
][]
=
[
'terms'
=>
[
'platform'
=>
Text
::
buildArray
(
$opts
[
'platform'
]),
],
];
}
if
(
$opts
[
'for'
])
{
if
(
!
isset
(
$body
[
'query'
][
'bool'
][
'must_not'
]))
{
$body
[
'query'
][
'bool'
][
'must_not'
]
=
[];
}
$body
[
'query'
][
'bool'
][
'must_not'
][]
=
[
'term'
=>
[
'user_guid'
=>
(
string
)
$opts
[
'for'
],
],
];
$body
[
'query'
][
'bool'
][
'must_not'
][]
=
[
'terms'
=>
[
'user_guid'
=>
[
'index'
=>
'minds-graph'
,
'type'
=>
'subscriptions'
,
'id'
=>
(
string
)
$opts
[
'for'
],
'path'
=>
'guids'
,
],
],
];
}
if
(
$opts
[
'except'
])
{
$body
[
'query'
][
'bool'
][
'must_not'
][]
=
[
'terms'
=>
[
'user_guid'
=>
$opts
[
'except'
],
],
];
}
if
(
$opts
[
'validated'
])
{
$body
[
'query'
][
'bool'
][
'must'
][]
=
[
'exists'
=>
[
'field'
=>
'user_phone_number_hash'
,
],
];
if
(
!
isset
(
$body
[
'query'
][
'bool'
][
'must_not'
]))
{
$body
[
'query'
][
'bool'
][
'must_not'
]
=
[];
}
$body
[
'query'
][
'bool'
][
'must_not'
][]
=
[
'term'
=>
[
'user_phone_number_hash'
=>
''
,
],
];
}
$query
=
[
'index'
=>
$this
->
index
,
'type'
=>
'action'
,
'body'
=>
$body
,
];
$prepared
=
new
Search
();
$prepared
->
query
(
$query
);
$result
=
$this
->
elasticsearch
->
request
(
$prepared
);
foreach
(
$result
[
'aggregations'
][
'entities'
][
'buckets'
]
as
$bucket
)
{
yield
$bucket
[
'key'
];
}
}
}
This diff is collapsed.
Click to expand it.
Core/Reports/Summons/Repository.php
View file @
ca945dff
...
...
@@ -8,6 +8,8 @@
namespace
Minds\Core\Reports\Summons
;
use
Cassandra\Bigint
;
use
Exception
;
use
Generator
;
use
Minds\Core\Data\Cassandra\Client
as
CassandraClient
;
use
Minds\Core\Data\Cassandra\Prepared\Custom
;
use
Minds\Core\Di\Di
;
...
...
@@ -30,11 +32,70 @@ class Repository
/**
* @param array $opts
* @throws \NotImplementedException
* @return Generator
* @yields array
* @throws Exception
*/
public
function
getList
(
array
$opts
=
[])
{
throw
new
\NotImplementedException
();
$opts
=
array_merge
([
'report_urn'
=>
null
,
'jury_type'
=>
null
,
'juror_guid'
=>
null
,
'limit'
=>
10000
,
'offset'
=>
null
,
],
$opts
);
if
(
!
$opts
[
'report_urn'
])
{
throw
new
Exception
(
'Invalid Report URN'
);
}
if
(
!
$opts
[
'jury_type'
])
{
throw
new
Exception
(
'Invalid Jury type'
);
}
$cql
=
"SELECT * FROM moderation_summons WHERE report_urn = ? AND jury_type = ?"
;
$values
=
[
$opts
[
'report_urn'
],
$opts
[
'jury_type'
],
];
$cqlOpts
=
[];
if
(
$opts
[
'juror_guid'
])
{
$cql
.=
" AND juror_guid = ?"
;
$values
[]
=
new
Bigint
(
$opts
[
'juror_guid'
]);
}
if
(
$opts
[
'offset'
])
{
$cqlOpts
[
'paging_state_token'
]
=
base64_decode
(
$opts
[
'offset'
]);
}
if
(
$opts
[
'limit'
])
{
$cqlOpts
[
'page_size'
]
=
(
int
)
$opts
[
'limit'
];
}
$prepared
=
new
Custom
();
$prepared
->
query
(
$cql
,
$values
);
$prepared
->
setOpts
(
$cqlOpts
);
try
{
$rows
=
$this
->
db
->
request
(
$prepared
);
foreach
(
$rows
as
$row
)
{
$summon
=
new
Summon
();
$summon
->
setReportUrn
(
$row
[
'report_urn'
])
->
setJuryType
(
$row
[
'jury_type'
])
->
setJurorGuid
(
$row
[
'juror_guid'
]
->
toInt
())
->
setStatus
(
$row
[
'status'
])
->
setTtl
(
$row
[
'expires'
]
-
time
());
yield
$summon
;
}
}
catch
(
Exception
$e
)
{
error_log
(
$e
);
return
[];
}
}
/**
...
...
@@ -60,7 +121,7 @@ class Repository
try
{
return
(
bool
)
$this
->
db
->
request
(
$prepared
,
true
);
}
catch
(
\
Exception
$e
)
{
}
catch
(
Exception
$e
)
{
error_log
(
$e
);
return
false
;
}
...
...
@@ -86,7 +147,7 @@ class Repository
$response
=
$this
->
db
->
request
(
$prepared
);
return
$response
[
0
][
'total'
]
>
0
;
}
catch
(
\
Exception
$e
)
{
}
catch
(
Exception
$e
)
{
error_log
(
$e
);
return
false
;
}
...
...
@@ -94,10 +155,59 @@ class Repository
/**
* @param Summon $summon
* @throws \NotImplementedException
* @return bool
* @throws Exception
*/
public
function
delete
(
Summon
$summon
)
{
throw
new
\NotImplementedException
();
return
$this
->
deleteAll
([
'report_urn'
=>
$summon
->
getReportUrn
(),
'jury_type'
=>
$summon
->
getJuryType
(),
'juror_guid'
=>
$summon
->
getJurorGuid
(),
]);
}
/**
* @param array $opts
* @return bool
* @throws Exception
* @yields array
*/
public
function
deleteAll
(
array
$opts
=
[])
{
$opts
=
array_merge
([
'report_urn'
=>
null
,
'jury_type'
=>
null
,
'juror_guid'
=>
null
,
],
$opts
);
if
(
!
$opts
[
'report_urn'
])
{
throw
new
Exception
(
'Invalid Report URN'
);
}
if
(
!
$opts
[
'jury_type'
])
{
throw
new
Exception
(
'Invalid Jury type'
);
}
$cql
=
"DELETE FROM moderation_summons WHERE report_urn = ? AND jury_type = ?"
;
$values
=
[
$opts
[
'report_urn'
],
$opts
[
'jury_type'
],
];
if
(
$opts
[
'juror_guid'
])
{
$cql
.=
" AND juror_guid = ?"
;
$values
[]
=
new
Bigint
(
$opts
[
'juror_guid'
]);
}
$prepared
=
new
Custom
();
$prepared
->
query
(
$cql
,
$values
);
try
{
return
(
bool
)
$this
->
db
->
request
(
$prepared
,
true
);
}
catch
(
Exception
$e
)
{
error_log
(
$e
);
return
false
;
}
}
}
This diff is collapsed.
Click to expand it.
Core/Reports/Summons/Summon.php
View file @
ca945dff
...
...
@@ -7,6 +7,8 @@
namespace
Minds\Core\Reports\Summons
;
use
Exception
;
use
JsonSerializable
;
use
Minds\Traits\MagicAttributes
;
/**
...
...
@@ -22,7 +24,7 @@ use Minds\Traits\MagicAttributes;
* @method int getTtl()
* @method Summon setTtl(int $ttl)
*/
class
Summon
implements
\
JsonSerializable
class
Summon
implements
JsonSerializable
{
use
MagicAttributes
;
...
...
@@ -44,12 +46,12 @@ class Summon implements \JsonSerializable
/**
* @param string $status
* @return $this
* @throws
\
Exception
* @throws Exception
*/
public
function
setStatus
(
$status
)
{
if
(
!
in_array
(
$status
,
[
'awaiting'
,
'accepted'
,
'declined'
]))
{
throw
new
\
Exception
(
'Invalid status'
);
throw
new
Exception
(
'Invalid status'
);
}
$this
->
status
=
$status
;
...
...
This diff is collapsed.
Click to expand it.
Core/Reports/Verdict/Delegates/ReleaseSummonsesDelegate.php
0 → 100644
View file @
ca945dff
<?php
/**
* ReleaseSummonsesDelegate
*
* @author edgebal
*/
namespace
Minds\Core\Reports\Verdict\Delegates
;
use
Minds\Core\Di\Di
;
use
Minds\Core\Reports\Summons\Manager
;
use
Minds\Core\Reports\Verdict\Verdict
;
class
ReleaseSummonsesDelegate
{
/** @var Manager */
protected
$summonsManager
;
/**
* ReleaseSummonsesDelegate constructor.
* @param Manager $summonsManager
*/
public
function
__construct
(
$summonsManager
=
null
)
{
$this
->
summonsManager
=
$summonsManager
?:
Di
::
_
()
->
get
(
'Moderation\Summons\Manager'
);
}
/**
* @param Verdict $verdict
* @throws \Exception
*/
public
function
onCast
(
Verdict
$verdict
)
{
$juryType
=
$verdict
->
isAppeal
()
?
'appeal_jury'
:
'initial_jury'
;
$this
->
summonsManager
->
release
(
$verdict
->
getReport
()
->
getUrn
(),
$juryType
);
}
}
This diff is collapsed.
Click to expand it.
Core/Reports/Verdict/Manager.php
View file @
ca945dff
...
...
@@ -32,17 +32,22 @@ class Manager
/** @var Delegates\NotificationDelegate $notificationDelegate */
private
$notificationDelegate
;
/** @var Delegates\ReleaseSummonsesDelegate $releaseSummonsesDelegate */
private
$releaseSummonsesDelegate
;
public
function
__construct
(
$repository
=
null
,
$actionDelegate
=
null
,
$reverseActionDelegate
=
null
,
$notificationDelegate
=
null
$notificationDelegate
=
null
,
$releaseSummonsesDelegate
=
null
)
{
$this
->
repository
=
$repository
?:
new
Repository
;
$this
->
actionDelegate
=
$actionDelegate
?:
new
Delegates\ActionDelegate
;
$this
->
reverseActionDelegate
=
$reverseActionDelegate
?:
new
Delegates\ReverseActionDelegate
;
$this
->
notificationDelegate
=
$notificationDelegate
?:
new
Delegates\NotificationDelegate
;
$this
->
releaseSummonsesDelegate
=
$releaseSummonsesDelegate
?:
new
Delegates\ReleaseSummonsesDelegate
;
}
/**
...
...
@@ -119,6 +124,7 @@ class Manager
* Cast a verdict
* @param Verdict $verdict
* @return boolean
* @throws \Exception
*/
public
function
cast
(
Verdict
$verdict
)
{
...
...
@@ -133,6 +139,9 @@ class Manager
// Send a notification to the reported user
$this
->
notificationDelegate
->
onAction
(
$verdict
);
// Release summonses
$this
->
releaseSummonsesDelegate
->
onCast
(
$verdict
);
// Send rewards to reporters
return
$added
;
...
...
This diff is collapsed.
Click to expand it.
Core/Reports/Verdict/Verdict.php
View file @
ca945dff
...
...
@@ -4,16 +4,16 @@
*/
namespace
Minds\Core\Reports\Verdict
;
use
Minds\Core\Reports\Jury\Decision
;
use
Minds\Core\Reports\Report
;
use
Minds\Traits\MagicAttributes
;
/**
* @method Report getReport(): Report
* @method Report getDecisions(): array<Decision>
* @method Report isAppeal(): boolean
* @method Report isUphold(): boolean
* @method Report getAction(): string
* @method Report getInitialJuryAction(): string
* @method Report getTimestamp: int
* @method Report getReport()
* @method boolean isUphold()
* @method string getAction()
* @method string getInitialJuryAction()
* @method int getTimestamp()
*/
class
Verdict
{
...
...
@@ -36,7 +36,7 @@ class Verdict
/**
* Decisions
* @return
array<Decision>
* @return
Decision[]
*/
public
function
getDecisions
()
{
...
...
This diff is collapsed.
Click to expand it.
Spec/Core/Reports/Verdict/ManagerSpec.php
View file @
ca945dff
...
...
@@ -18,19 +18,22 @@ class ManagerSpec extends ObjectBehavior
private
$actionDelegate
;
private
$reverseDelegate
;
private
$notificationDelegate
;
private
$releaseSummonsesDelegate
;
function
let
(
Repository
$repository
,
Delegates\ActionDelegate
$actionDelegate
,
Delegates\ReverseActionDelegate
$reverseDelegate
,
Delegates\NotificationDelegate
$notificationDelegate
Delegates\NotificationDelegate
$notificationDelegate
,
Delegates\ReleaseSummonsesDelegate
$releaseSummonsesDelegate
)
{
$this
->
beConstructedWith
(
$repository
,
$actionDelegate
,
$reverseDelegate
,
$notificationDelegate
);
$this
->
beConstructedWith
(
$repository
,
$actionDelegate
,
$reverseDelegate
,
$notificationDelegate
,
$releaseSummonsesDelegate
);
$this
->
repository
=
$repository
;
$this
->
actionDelegate
=
$actionDelegate
;
$this
->
reverseDelegate
=
$reverseDelegate
;
$this
->
notificationDelegate
=
$notificationDelegate
;
$this
->
releaseSummonsesDelegate
=
$releaseSummonsesDelegate
;
}
...
...
@@ -60,6 +63,9 @@ class ManagerSpec extends ObjectBehavior
$this
->
notificationDelegate
->
onAction
(
$verdict
)
->
shouldBeCalled
();
$this
->
releaseSummonsesDelegate
->
onCast
(
$verdict
)
->
shouldBeCalled
();
$this
->
cast
(
$verdict
->
getWrappedObject
());
}
...
...
This diff is collapsed.
Click to expand it.