...
 
Commits (9)
......@@ -14,6 +14,7 @@ use Minds\Common\Access;
use Minds\Core;
use Minds\Helpers;
use Minds\Interfaces;
use Minds\Core\Blogs\Delegates\CreateActivity;
class blog implements Interfaces\Api
{
......@@ -333,11 +334,9 @@ class blog implements Interfaces\Api
}
if ($saved) {
$createActivity = new Core\Blogs\Delegates\CreateActivity();
if ($blog->isPublished() && $blog->getAccessId() == Access::PUBLIC) {
if (!$editing || ($editing && !$alreadyPublished) || ($editing && $oldAccessId == Access::UNLISTED)) {
$createActivity->save($blog);
(new CreateActivity())->save($blog);
}
}
......
......@@ -77,7 +77,8 @@ class phone implements Interfaces\Api
return Factory::response(['status' => 'success', 'message' => 'voip phones not allowed']);
}
$sms->send($phone, $code);
$message = 'From Minds.com: Your code is '. $code;
$sms->send($phone, $message);
return Factory::response(['status' => 'success', 'secret' => $secret]);
}
......
......@@ -43,6 +43,8 @@ class settings implements Interfaces\Api
$response['channel']['email'] = $user->getEmail();
$response['channel']['boost_rating'] = $user->getBoostRating();
$response['channel']['disabled_emails'] = $user->disabled_emails;
$response['channel']['toaster_notifications'] = $user->getToasterNotifications();
$sessionsManager = Di::_()->get('Sessions\Manager');
$sessionsManager->setUser($user);
......@@ -140,6 +142,10 @@ class settings implements Interfaces\Api
$user->setLanguage($_POST['language']);
}
if (isset($_POST['toaster_notifications'])) {
$user->setToasterNotifications((bool) $_POST['toaster_notifications']);
}
$response = [];
if (!$user->save()) {
$response['status'] = 'error';
......
......@@ -59,7 +59,7 @@ class twofactor implements Interfaces\Api
switch ($pages[0]) {
case "setup":
$secret = $twofactor->createSecret();
$secret = $twofactor->createSecret();
/** @var Core\SMS\SMSServiceInterface $sms */
$sms = Core\Di\Di::_()->get('SMS');
......@@ -67,7 +67,9 @@ class twofactor implements Interfaces\Api
if (!$sms->verify($_POST['tel'])) {
return Factory::response(['status' => 'error', 'message' => 'voip phones are not supported']);
}
if ($sms->send($_POST['tel'], $twofactor->getCode($secret))) {
$message = 'From Minds.com: Your code is '. $twofactor->getCode($secret);
if ($sms->send($_POST['tel'], $message)) {
$response['secret'] = $secret;
} else {
$response['status'] = "error";
......
......@@ -9,6 +9,7 @@
namespace Minds\Core\Blogs\Delegates;
use Minds\Core\Blogs\Blog;
use Minds\Core\Data\Call;
use Minds\Core\Entities\Actions\Save;
use Minds\Entities\Activity;
......@@ -17,22 +18,32 @@ class CreateActivity
/** @var Save */
protected $saveAction;
/** @var Call */
protected $db;
/**
* CreateActivity constructor.
* @param null $saveAction
*/
public function __construct($saveAction = null)
public function __construct($saveAction = null, Call $db=null)
{
$this->saveAction = $saveAction ?: new Save();
$this->db = $db ?? new Call('entities_by_time');
}
/**
* Creates a new activity for a blog
* @param Blog $blog
* @throws \Minds\Exceptions\StopEventException
* @return bool
*/
public function save(Blog $blog)
public function save(Blog $blog) : bool
{
$activities = $this->db->getRow("activity:entitylink:{$blog->getGuid()}");
if (!empty($activities)) {
return false;
}
$owner = $blog->getOwnerEntity();
$activity = (new Activity())
......@@ -53,5 +64,7 @@ class CreateActivity
$this->saveAction
->setEntity($activity)
->save();
return true;
}
}
......@@ -8,6 +8,7 @@
namespace Minds\Core\Comments;
use Minds\Common\Urn;
use Minds\Core\Di\Di;
use Minds\Core\EntitiesBuilder;
use Minds\Core\Luid;
......@@ -69,7 +70,7 @@ class Manager
$this->threadNotifications = $threadNotifications ?: new Delegates\ThreadNotifications();
$this->createEventDispatcher = $createEventDispatcher ?: new Delegates\CreateEventDispatcher();
$this->countCache = $countCache ?: new Delegates\CountCache();
$this->entitiesBuilder = $entitiesBuilder ?: Di::_()->get('EntitiesBuilder');
$this->entitiesBuilder = $entitiesBuilder ?: Di::_()->get('EntitiesBuilder');
$this->spam = $spam ?: Di::_()->get('Security\Spam');
}
......@@ -95,7 +96,7 @@ class Manager
}
$response = $this->repository->getList($opts);
if ($opts['is_focused'] === true && $opts['offset']) {
$count = count($response);
$diff = $opts['limit'] - $count;
......@@ -229,8 +230,8 @@ class Manager
public function delete(Comment $comment, $opts = [])
{
$opts = array_merge([
'force' => false,
], $opts);
'force' => false,
], $opts);
if (!$this->acl->write($comment) && !$opts['force']) {
return false; //TODO throw exception
......@@ -271,6 +272,34 @@ class Manager
return null;
}
/**
* @param string|Urn $urn
* @return Comment|null
* @throws \Exception
*/
public function getByUrn($urn)
{
if (is_string($urn)) {
$urn = new Urn($urn);
}
$components = explode(':', $urn->getNss());
if (count($components) !== 5) {
error_log("[CommentsManager]: Invalid Comment URN (${$components})");
return null;
}
$entityGuid = $components[0];
$parentPath = "{$components[1]}:{$components[2]}:{$components[3]}";
$guid = $components[4];
if ($this->legacyRepository->isLegacy($entityGuid)) {
return $this->legacyRepository->getByGuid($guid);
}
return $this->repository->get($entityGuid, $parentPath, $guid);
}
/**
* Counts comments on an entity
* @param int $entity_guid
......
......@@ -16,7 +16,7 @@ use Minds\Entities\Boost\BoostEntityInterface;
class BoostGuidResolverDelegate implements ResolverDelegate
{
/**
* @var Manager
* @var Manager
*/
protected $manager;
......
<?php
/**
* @author: Marcelo
*/
namespace Minds\Core\Entities\Delegates;
use Minds\Common\Urn;
use Minds\Core\Boost\Repository;
use Minds\Core\Comments\Comment;
use Minds\Core\Comments\Manager;
use Minds\Core\Di\Di;
use Minds\Core\EntitiesBuilder;
use Minds\Entities\Boost\BoostEntityInterface;
class CommentGuidResolverDelegate implements ResolverDelegate
{
/**
* @var Manager
*/
protected $manager;
/**
* CommentGuidResolverDelegate constructor.
* @param Manager $manager
*/
public function __construct($manager = null)
{
$this->manager = $manager ?: new Manager();
}
/**
* @param Urn $urn
* @return boolean
*/
public function shouldResolve(Urn $urn)
{
return $urn->getNid() === 'comment';
}
/**
* @param array $urns
* @param array $opts
* @return mixed
*/
public function resolve(array $urns, array $opts = [])
{
$entities = [];
foreach ($urns as $urn) {
/** @var Comment $comment */
$comment = $this->manager->getByUrn($urn);
$entities[] = $comment;
}
return $entities;
}
/**
* @param $urn
* @param Comment $entity
* @return mixed
*/
public function map($urn, $entity)
{
return $entity;
}
/**
* @param Comment $entity
* @return string|null
*/
public function asUrn($entity)
{
if (!$entity) {
return null;
}
return $entity->getUrn();
}
}
\ No newline at end of file
......@@ -79,6 +79,7 @@ class EntityGuidResolverDelegate implements ResolverDelegate
}
/**
* @param $urn
* @param mixed $entity
* @return mixed
*/
......
......@@ -8,12 +8,12 @@
namespace Minds\Core\Entities;
use Minds\Common\Urn;
use Minds\Core\Entities\Delegates\EntityGuidResolverDelegate;
use Minds\Core\Entities\Delegates\BoostGuidResolverDelegate;
use Minds\Core\Entities\Delegates\CommentGuidResolverDelegate;
use Minds\Core\Entities\Delegates\EntityGuidResolverDelegate;
use Minds\Core\Entities\Delegates\ResolverDelegate;
use Minds\Core\Security\ACL;
use Minds\Entities\User;
use Minds\Helpers\Flags;
class Resolver
{
......@@ -42,6 +42,7 @@ class Resolver
$this->resolverDelegates = $resolverDelegates ?: [
EntityGuidResolverDelegate::class => new EntityGuidResolverDelegate(),
BoostGuidResolverDelegate::class => new BoostGuidResolverDelegate(),
CommentGuidResolverDelegate::class => new CommentGuidResolverDelegate(),
];
$this->acl = $acl ?: ACL::_();
......@@ -122,7 +123,7 @@ class Resolver
// Filter out invalid entities
$sorted = array_filter($sorted, function($entity) { return (bool) $entity; });
$sorted = array_filter($sorted, function ($entity) { return (bool) $entity; });
// Filter out forbidden entities, if not ignoring ACL
......@@ -142,7 +143,7 @@ class Resolver
public function single($urn)
{
$this->urns = [ $urn ];
$this->urns = [$urn];
$entities = $this->fetch();
return $entities[0];
}
......
......@@ -2,12 +2,15 @@
/**
* Notification delegate for Verdicts
*/
namespace Minds\Core\Reports\Verdict\Delegates;
use Minds\Common\Urn;
use Minds\Core\Di\Di;
use Minds\Core\Reports\Verdict\Verdict;
use Minds\Core\Entities\Resolver;
use Minds\Core\EntitiesBuilder;
use Minds\Core\Events\EventsDispatcher;
use Minds\Common\Urn;
use Minds\Core\Reports\Verdict\Verdict;
class NotificationDelegate
{
......@@ -18,25 +21,36 @@ class NotificationDelegate
protected $entitiesBuilder;
/** @var Urn $urn */
protected $urn;
public function __construct($dispatcher = null, $entitiesBuilder = null, $urn = null)
/** @var Resolver */
protected $entitiesResolver;
public function __construct($dispatcher = null, $entitiesBuilder = null, $urn = null, $entitiesResolver = null)
{
$this->dispatcher = $dispatcher ?: Di::_()->get('EventsDispatcher');
$this->entitiesBuilder = $entitiesBuilder ?: Di::_()->get('EntitiesBuilder');
$this->urn = $urn ?: new Urn;
$this->entitiesResolver = $entitiesResolver ?: new Resolver();
}
/**
* Actioned notification
* @param Verdict $verdict
* @return void
* @throws \Exception
*/
public function onAction(Verdict $verdict)
{
$entityUrn = $verdict->getReport()->getEntityUrn();
$entityGuid = $this->urn->setUrn($entityUrn)->getNss();
$entity = $this->entitiesBuilder->single($entityGuid);
$entity = $this->entitiesResolver->single($this->urn->setUrn($entityUrn));
if (!$entity) {
$entityGuid = $this->urn->setUrn($entityUrn)->getNss();
$entity = $this->entitiesBuilder->single($entityGuid);
}
if ($verdict->isUpheld()) {
$readableAction = 'removed';
......@@ -58,13 +72,13 @@ class NotificationDelegate
} else {
$readableAction .= '. You can appeal this decision';
}
$this->dispatcher->trigger('notification', 'all', [
'to' => [$entity->getOwnerGuid()],
'entity' => $entity,
'from' => 100000000000000519,
'notification_view' => 'report_actioned',
'params' => [ 'action' => $readableAction ],
'params' => ['action' => $readableAction],
]);
}
......
......@@ -43,7 +43,7 @@ class User extends \ElggUser
$this->attributes['briefdescription'] = '';
$this->attributes['rating'] = 1;
$this->attributes['p2p_media_enabled'] = 0;
$this->attributes['is_mature'] = 0;
$this->attributes['is_mature'] = 0;
$this->attributes['mature_lock'] = 0;
$this->attributes['opted_in_hashtags'] = 0;
$this->attributes['last_accepted_tos'] = Core\Config::_()->get('last_tos_update');
......@@ -52,6 +52,7 @@ class User extends \ElggUser
$this->attributes['last_avatar_upload'] = 0;
$this->attributes['canary'] = 0;
$this->attributes['onchain_booster'] = null;
$this->attributes['toaster_notifications'] = 1;
parent::initializeAttributes();
}
......@@ -739,6 +740,7 @@ class User extends \ElggUser
$export['is_admin'] = $this->attributes['admin'] == 'yes';
$export['theme'] = $this->getTheme();
$export['onchain_booster'] = $this->getOnchainBooster();
$export['toaster_notifications'] = $this->getToasterNotifications();
if (is_string($export['social_profiles'])) {
$export['social_profiles'] = json_decode($export['social_profiles']);
......@@ -987,7 +989,8 @@ class User extends \ElggUser
'last_avatar_upload',
'canary',
'theme',
'onchain_booster'
'onchain_booster',
'toaster_notifications'
));
}
......@@ -1075,4 +1078,21 @@ class User extends \ElggUser
$this->onchain_booster = (int) $time;
return $this;
}
/**
* Returns toaster notifications state.
* @return boolean true if toaster notifications is enabled.
*/
public function getToasterNotifications()
{
return (bool) $this->toaster_notifications;
}
/**
* Set on/off toaster notifications
*/
public function setToasterNotifications($enabled = true)
{
$this->toaster_notifications = $enabled ? 1 : 0;
}
}
......@@ -3,6 +3,7 @@
namespace Spec\Minds\Core\Blogs\Delegates;
use Minds\Core\Blogs\Blog;
use Minds\Core\Data\Call;
use Minds\Core\Entities\Actions\Save;
use Minds\Entities\Activity;
use Minds\Entities\User;
......@@ -14,12 +15,16 @@ class CreateActivitySpec extends ObjectBehavior
/** @var Save */
protected $saveAction;
/** @var Call */
protected $db;
function let(
Save $saveAction
Save $saveAction,
Call $db
) {
$this->beConstructedWith($saveAction);
$this->beConstructedWith($saveAction, $db);
$this->saveAction = $saveAction;
$this->db = $db;
}
function it_is_initializable()
......@@ -27,7 +32,7 @@ class CreateActivitySpec extends ObjectBehavior
$this->shouldHaveType('Minds\Core\Blogs\Delegates\CreateActivity');
}
function it_should_save(
function it_should_save_when_no_activity(
Blog $blog,
User $user
)
......@@ -64,6 +69,10 @@ class CreateActivitySpec extends ObjectBehavior
->shouldBeCalled()
->willReturn(false);
$blog->getGuid()
->shouldBeCalled()
->willReturn(9999);
$user->export()
->shouldBeCalled()
->willReturn([]);
......@@ -72,6 +81,10 @@ class CreateActivitySpec extends ObjectBehavior
->shouldBeCalled()
->willReturn(1000);
$this->db->getRow("activity:entitylink:9999")
->shouldBeCalled()
->willReturn([]);
$this->saveAction->setEntity(Argument::type(Activity::class))
->shouldBeCalled()
->willReturn($this->saveAction);
......@@ -82,7 +95,23 @@ class CreateActivitySpec extends ObjectBehavior
$this
->save($blog)
->shouldNotThrow();
->shouldReturn(true);
}
function it_should_not_save_when_previous_activity(
Blog $blog
)
{
$blog->getGuid()
->shouldBeCalled()
->willReturn(9999);
$this->db->getRow("activity:entitylink:9999")
->shouldBeCalled()
->willReturn(['activity1']);
$this
->save($blog)
->shouldReturn(false);
}
}
......@@ -2,11 +2,13 @@
namespace Spec\Minds\Core\Reports\Verdict\Delegates;
use Minds\Common\Urn;
use Minds\Core\Entities\Resolver;
use Minds\Core\EntitiesBuilder;
use Minds\Core\Events\EventsDispatcher;
use Minds\Core\Reports\Report;
use Minds\Core\Reports\Verdict\Delegates\NotificationDelegate;
use Minds\Core\Reports\Verdict\Verdict;
use Minds\Core\Reports\Report;
use Minds\Core\Events\EventsDispatcher;
use Minds\Core\EntitiesBuilder;
use Minds\Entities\Entity;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
......@@ -19,11 +21,19 @@ class NotificationDelegateSpec extends ObjectBehavior
/** @var EntitiesBuilder $entitiesBuilder */
private $entitiesBuilder;
function let(EventsDispatcher $dispatcher, EntitiesBuilder $entitiesBuilder)
/** @var Urn */
private $urn;
/** @var Resolver */
private $entitiesResolver;
function let(EventsDispatcher $dispatcher, EntitiesBuilder $entitiesBuilder, Urn $urn, Resolver $entitiesResolver)
{
$this->beConstructedWith($dispatcher, $entitiesBuilder);
$this->beConstructedWith($dispatcher, $entitiesBuilder, $urn, $entitiesResolver);
$this->dispatcher = $dispatcher;
$this->entitiesBuilder = $entitiesBuilder;
$this->urn = $urn;
$this->entitiesResolver = $entitiesResolver;
}
function it_is_initializable()
......@@ -37,6 +47,18 @@ class NotificationDelegateSpec extends ObjectBehavior
->shouldBeCalled()
->willReturn('urn:activity:123');
$this->urn->setUrn('urn:activity:123')
->shouldBeCalled()
->willReturn($this->urn);
$this->entitiesResolver->single($this->urn)
->shouldBeCalled()
->willReturn(null);
$this->urn->getNss()
->shouldBeCalled()
->willReturn('123');
$report->getReasonCode()
->shouldBeCalled()
->willReturn(2);
......@@ -54,7 +76,43 @@ class NotificationDelegateSpec extends ObjectBehavior
$this->entitiesBuilder->single(123)
->willReturn($entity);
$this->dispatcher->trigger('notification', 'all', Argument::that(function($opts) {
$this->dispatcher->trigger('notification', 'all', Argument::that(function ($opts) {
return $opts['params']['action'] === 'marked as nsfw. You can appeal this decision';
}))
->shouldBeCalled();
$this->onAction($verdict);
}
function it_should_send_a_marked_as_nsfw_notification_but_resolving_urn_with_entitiesResolver(Verdict $verdict, Report $report, Entity $entity)
{
$report->getEntityUrn()
->shouldBeCalled()
->willReturn('urn:activity:123');
$this->urn->setUrn('urn:activity:123')
->shouldBeCalled()
->willReturn($this->urn);
$this->entitiesResolver->single($this->urn)
->shouldBeCalled()
->willReturn($entity);
$report->getReasonCode()
->shouldBeCalled()
->willReturn(2);
$report->isAppeal()
->shouldBeCalled()
->willReturn(false);
$verdict->getReport()
->willReturn($report);
$verdict->isUpheld()
->willReturn(true);
$this->dispatcher->trigger('notification', 'all', Argument::that(function ($opts) {
return $opts['params']['action'] === 'marked as nsfw. You can appeal this decision';
}))
->shouldBeCalled();
......@@ -68,6 +126,18 @@ class NotificationDelegateSpec extends ObjectBehavior
->shouldBeCalled()
->willReturn('urn:activity:123');
$this->urn->setUrn('urn:activity:123')
->shouldBeCalled()
->willReturn($this->urn);
$this->entitiesResolver->single($this->urn)
->shouldBeCalled()
->willReturn(null);
$this->urn->getNss()
->shouldBeCalled()
->willReturn('123');
$report->getReasonCode()
->shouldBeCalled()
->willReturn(4);
......@@ -85,7 +155,7 @@ class NotificationDelegateSpec extends ObjectBehavior
$this->entitiesBuilder->single(123)
->willReturn($entity);
$this->dispatcher->trigger('notification', 'all', Argument::that(function($opts) {
$this->dispatcher->trigger('notification', 'all', Argument::that(function ($opts) {
return $opts['params']['action'] === 'removed. You can appeal this decision';
}))
->shouldBeCalled();
......@@ -99,6 +169,18 @@ class NotificationDelegateSpec extends ObjectBehavior
->shouldBeCalled()
->willReturn('urn:activity:123');
$this->urn->setUrn('urn:activity:123')
->shouldBeCalled()
->willReturn($this->urn);
$this->entitiesResolver->single($this->urn)
->shouldBeCalled()
->willReturn(null);
$this->urn->getNss()
->shouldBeCalled()
->willReturn('123');
$report->isAppeal()
->shouldBeCalled()
->willReturn(true);
......@@ -112,7 +194,7 @@ class NotificationDelegateSpec extends ObjectBehavior
$this->entitiesBuilder->single(123)
->willReturn($entity);
$this->dispatcher->trigger('notification', 'all', Argument::that(function($opts) {
$this->dispatcher->trigger('notification', 'all', Argument::that(function ($opts) {
return $opts['params']['action'] === 'restored by the community appeal jury';
}))
->shouldBeCalled();
......@@ -126,6 +208,18 @@ class NotificationDelegateSpec extends ObjectBehavior
->shouldBeCalled()
->willReturn('urn:activity:123');
$this->urn->setUrn('urn:activity:123')
->shouldBeCalled()
->willReturn($this->urn);
$this->entitiesResolver->single($this->urn)
->shouldBeCalled()
->willReturn(null);
$this->urn->getNss()
->shouldBeCalled()
->willReturn('123');
$report->isAppeal()
->shouldBeCalled()
->willReturn(false);
......