at the end of the day, it was inevitable

This commit is contained in:
Mo Elzubeir
2022-12-09 08:36:26 -06:00
commit 1218570914
1768 changed files with 887087 additions and 0 deletions
@@ -0,0 +1,124 @@
<?php
namespace UserBundle\Controller\V1;
use ApiBundle\Controller\AbstractCRUDController;
use ApiBundle\Form\ActivatedEntitiesBatchType;
use ApiBundle\Form\EntitiesBatchType;
use ApiBundle\Form\SubscribeToNotificationsBatchType;
use ApiBundle\Security\Inspector\InspectorInterface;
use Doctrine\Common\Collections\Collection;
use Symfony\Component\HttpFoundation\Request;
use UserBundle\Manager\Notification\NotificationManagerInterface;
use UserBundle\Security\Inspector\NotificationInspector;
use UserBundle\UserBundleServices;
/**
* Class AbstractRecipientController
*
* @package UserBundle\Controller\V1
*/
abstract class AbstractRecipientController extends AbstractCRUDController
{
/**
* Batch remove of recipients.
*
* @param Request $request A HTTP Request instance.
*
* @return \ApiBundle\Response\ViewInterface
*/
protected function batchDelete(Request $request)
{
$processor = function (Collection $recipients) {
$em = $this->getManager();
foreach ($recipients as $recipient) {
$em->remove($recipient);
}
$em->flush();
};
return $this->batchProcessing(
$request,
InspectorInterface::DELETE,
EntitiesBatchType::class,
$processor
);
}
/**
* Batch activate/deactivate recipients.
*
* @param Request $request A HTTP Request instance.
*
* @return \ApiBundle\Response\ViewInterface
*/
protected function batchActiveToggle(Request $request)
{
$processor = function (Collection $recipients, $active) {
$em = $this->getManager();
foreach ($recipients as $recipient) {
$recipient->setActive($active);
$em->persist($recipient);
}
$em->flush();
};
return $this->batchProcessing(
$request,
InspectorInterface::UPDATE,
ActivatedEntitiesBatchType::class,
$processor
);
}
/**
* Batch subscribe/unsubscribe specified recipient from notifications.
*
* @param Request $request A HTTP Request instance.
* @param integer $id A recipient entity instance.
*
* @return \ApiBundle\Response\ViewInterface
*/
protected function batchSubscriptionToggle(Request $request, $id)
{
$recipient = $this->getManager()->getRepository($this->entity)->find($id);
if ($recipient === null) {
$name = \app\c\getShortName($this->entity);
// Remove 'Abstract' prefix if it exists.
if (strpos($name, 'Abstract') !== false) {
$name = substr($name, 8);
}
return $this->generateResponse("Can't find {$name} with id {$id}.", 404);
}
$reasons = $this->checkAccess(NotificationInspector::UPDATE, $recipient);
if (count($reasons) > 0) {
return $this->generateResponse($reasons, 403);
}
$processor = function (Collection $notifications, $subscribed) use ($recipient) {
/** @var NotificationManagerInterface $manager */
$manager = $this->get(UserBundleServices::NOTIFICATION_MANAGER);
$manager->subscriptionToggle(
$recipient,
$notifications->toArray(),
(bool) $subscribed
);
};
return $this->batchProcessing(
$request,
function (Collection $notifications, $subscribed) {
return $subscribed ? NotificationInspector::SUBSCRIBE : NotificationInspector::UNSUBSCRIBE;
},
SubscribeToNotificationsBatchType::class,
$processor
);
}
}
@@ -0,0 +1,272 @@
<?php
namespace UserBundle\Controller\V1;
use ApiBundle\Controller\AbstractApiController;
use ApiBundle\Controller\Annotation\Roles;
use FOS\UserBundle\Model\UserManagerInterface;
use Nelmio\ApiDocBundle\Annotation\ApiDoc;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Request;
use UserBundle\Entity\User;
use UserBundle\Enum\UserRoleEnum;
use UserBundle\Form\SubscriberType;
use UserBundle\Mailer\MailerInterface;
use UserBundle\Repository\UserRepository;
use UserBundle\UserBundleServices;
/**
* Class CurrentSubscriberController
* @package UserBundle\Controller\V1
*
* @Route(
* "/users/current/subscribers",
* service="user.controller.current_subscriber"
* )
*/
class CurrentSubscriberController extends AbstractApiController
{
/**
* Get list of subscriber for current master.
*
* @Roles("ROLE_MASTER_USER")
*
* @Route("", methods={ "GET" })
* @ApiDoc(
* resource="Current user subscribers",
* section="User",
* filters={
* {
* "name"="page",
* "dataType"="integer",
* "description"="Requested page number, start from 1",
* "requirements"="\d+",
* "default"="1"
* },
* {
* "name"="limit",
* "dataType"="integer",
* "description"="Max entities per page, default 100",
* "requirements"="\d+",
* "default"="100"
* }
* },
* output={
* "class"="Pagination<UserBundle\Entity\User>",
* "groups"={ "subscriber", "id" }
* },
* statusCodes={
* 200="Subscribers successfully returned."
* }
* )
*
* @param Request $request A Request instance.
*
* @return \ApiBundle\Response\ViewInterface
*/
public function listAction(Request $request)
{
/** @var UserRepository $repository */
$repository = $this->getManager()->getRepository('UserBundle:User');
$user = $this->getCurrentUser();
$pagination = $this->paginate(
$request,
$repository->getSubscribersQueryBuilder($user->getId())
);
return $this->generateResponse($pagination, 200, [ 'subscriber', 'id' ]);
}
/**
* Get information about subscriber.
*
* @Roles("ROLE_MASTER_USER")
*
* @Route("/{id}", requirements={ "id"="\d+" }, methods={ "GET" })
* @ApiDoc(
* resource="Current user subscribers",
* section="User",
* output={
* "class"="Pagination<UserBundle\Entity\User>",
* "groups"={ "subscriber", "id" }
* },
* statusCodes={
* 200="Subscriber successfully returned."
* }
* )
*
* @param integer $id A subscriber User entity id.
*
* @return \ApiBundle\Response\ViewInterface
*/
public function getAction($id)
{
/** @var UserManagerInterface $manager */
$manager = $this->get('fos_user.user_manager');
$current = $this->getCurrentUser();
$user = $manager->findUserBy([
'id' => $id,
'masterUser' => $current->getId(),
]);
if ($user === null) {
return $this->generateResponse("Can't find subscriber with id {$id}.", 404);
}
return $this->generateResponse($user, 200, [ 'subscriber', 'id' ]);
}
/**
* Create new subscriber for current user.
*
* @Roles("ROLE_MASTER_USER")
*
* @Route("", methods={ "POST" })
* @ApiDoc(
* resource="Current user subscribers",
* section="User",
* input={
* "class"="UserBundle\Form\SubscriberType",
* "name"=false
* },
* output={
* "class"="Pagination<UserBundle\Entity\User>",
* "groups"={ "subscriber", "id" }
* },
* statusCodes={
* 200="Subscriber successfully created."
* }
* )
*
* @param Request $request A Request instance.
*
* @return User|\ApiBundle\Response\ViewInterface
*/
public function createAction(Request $request)
{
$current = $this->getCurrentUser();
$user = new User();
$user
->generatePassword()
->setMasterUser($current)
->setRoles([ UserRoleEnum::SUBSCRIBER ]);
$form = $this->createForm(SubscriberType::class, $user);
$form->submit($request->request->all());
if ($form->isValid()) {
/** @var UserManagerInterface $manager */
$manager = $this->get('fos_user.user_manager');
$password = $user->getPlainPassword();
$manager->updateUser($user);
/** @var MailerInterface $mailer */
$mailer = $this->get(UserBundleServices::MAILER);
$mailer->sendPassword($user, $password);
return $this->generateResponse($user, 200, [ 'subscriber', 'id' ]);
}
return $this->generateResponse($form, 400);
}
/**
* Update current user subscriber.
*
* @Roles("ROLE_MASTER_USER")
*
* @Route("/{id}", requirements={ "id"="\d+" }, methods={ "PUT" })
* @ApiDoc(
* resource="Current user subscribers",
* section="User",
* input={
* "class"="UserBundle\Form\SubscriberType",
* "name"=false
* },
* output={
* "class"="Pagination<UserBundle\Entity\User>",
* "groups"={ "subscriber", "id" }
* },
* statusCodes={
* 200="Subscriber successfully updated.",
* 404="Can't find category by specified id."
* }
* )
*
* @param Request $request A Request instance.
* @param integer $id A subscriber User entity id.
*
* @return \ApiBundle\Response\ViewInterface
*/
public function putAction(Request $request, $id)
{
/** @var UserManagerInterface $manager */
$manager = $this->get('fos_user.user_manager');
$current = $this->getCurrentUser();
$user = $manager->findUserBy([
'id' => $id,
'masterUser' => $current->getId(),
]);
if ($user === null) {
return $this->generateResponse("Can't find subscriber with id {$id}.", 404);
}
$form = $this->createForm(SubscriberType::class, $user, [
'method' => 'PUT',
]);
$form->submit($request->request->all());
if ($form->isValid()) {
$manager->updateUser($user);
return $this->generateResponse($user, 200, [ 'subscriber', 'id' ]);
}
return $this->generateResponse($form, 400);
}
/**
* Update current user subscriber.
*
* @Roles("ROLE_MASTER_USER")
*
* @Route("/{id}", requirements={ "id"="\d+" }, methods={ "DELETE" })
* @ApiDoc(
* resource="Current user subscribers",
* section="User",
* statusCodes={
* 200="Subscriber successfully deleted.",
* 404="Can't find category by specified id."
* }
* )
*
* @param integer $id A subscriber User entity id.
*
* @return \ApiBundle\Response\ViewInterface
*/
public function deleteAction($id)
{
/** @var UserManagerInterface $manager */
$manager = $this->get('fos_user.user_manager');
$current = $this->getCurrentUser();
$user = $manager->findUserBy([
'id' => $id,
'masterUser' => $current->getId(),
]);
if ($user === null) {
return $this->generateResponse("Can't find subscriber with id {$id}.", 404);
}
$manager->deleteUser($user);
return $this->generateResponse();
}
}
@@ -0,0 +1,440 @@
<?php
namespace UserBundle\Controller\V1;
use ApiBundle\Controller\Annotation\Roles;
use ApiBundle\Security\Inspector\InspectorInterface;
use AppBundle\Model\SortingOptions;
use Doctrine\ORM\EntityManagerInterface;
use Knp\Bundle\PaginatorBundle\Pagination\SlidingPagination;
use Nelmio\ApiDocBundle\Annotation\ApiDoc;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Request;
use UserBundle\Entity\Recipient\AbstractRecipient;
use UserBundle\Entity\Recipient\GroupRecipient;
use UserBundle\Entity\Recipient\PersonRecipient;
use UserBundle\Enum\StatusFilterEnum;
use UserBundle\Repository\GroupRecipientRepository;
use UserBundle\Repository\PersonRecipientRepository;
use UserBundle\Utils\AdditionalConditions;
/**
* Class GroupRecipientController
* @package UserBundle\Controller\V1
*
* @Route(
* "/recipients/groups",
* service="user.controller.group_recipient"
* )
*/
class GroupRecipientController extends AbstractRecipientController
{
/**
* Get list of available person recipients.
*
* @Roles("ROLE_MASTER_USER")
*
* @Route("", methods={ "GET" })
* @ApiDoc(
* resource="Group",
* section="Receivers",
* filters={
* {
* "name"="page",
* "dataType"="integer",
* "description"="Requested page number, start from 1",
* "requirements"="\d+",
* "default"="1"
* },
* {
* "name"="limit",
* "dataType"="integer",
* "description"="Max entities per page, default 100",
* "requirements"="\d+",
* "default"="100"
* },
* {
* "name"="recipientId",
* "dataType"="string",
* "description"="If set get recipients for specified recipient group",
* "requirements"="\d+",
* "required"=false
* },
* {
* "name"="sortField",
* "dataType"="string",
* "description"="Field name for sorting. Available: name, active, recipientsNumber, creationDate",
* "requirements"="\w+",
* "default"="name",
* "required"=false
* },
* {
* "name"="sortDirection",
* "dataType"="string",
* "description"="Sort direction. Available: asc, desc",
* "requirements"="(asc|desc)",
* "default"="asc",
* "required"=false
* },
* {
* "name"="filter",
* "dataType"="string",
* "description"="Keyword for searching groups by names",
* "requirements"="\w+"
* },
* {
* "name"="statusFilter",
* "dataType"="string",
* "description"="Keyword for searching groups by status",
* "requirements"="(no|yes|all)"
* },
* {
* "name"="include",
* "dataType"="string",
* "description"="Comma separated list of recipient group ids."
* },
* {
* "name"="exclude",
* "dataType"="string",
* "description"="Comma separated list of recipient group ids."
* }
* },
* output={
* "class"="",
* "data"={
* "groups"={
* "class"="UserBundle\Entity\Recipient\PersonRecipient",
* "groups"={ "id", "recipient" }
* },
* "meta"={
* "dataType"="model",
* "description"="Response meta information",
* "required"=true,
* "readonly"=true,
* "children"={
* "sort"={
* "dataType"="model",
* "requited"=true,
* "readonly"=true,
* "children"={
* "field"={
* "dataType"="string",
* "description"="Field name for sorting. Available: name, email, creationDate, active",
* "required"=true,
* "readonly"=true
* },
* "direction"={
* "dataType"="string",
* "description"="Sort direction. Available: asc, desc",
* "required"=true,
* "readonly"=true
* }
* }
* }
* }
* }
* }
* },
* statusCodes={
* 200="Recipients groups successfully funded.",
* 403="Don't has requested permissions."
* }
* )
*
* @param Request $request A Request instance.
*
* @return \ApiBundle\Response\ViewInterface
*/
public function listAction(Request $request)
{
/** @var EntityManagerInterface $em */
$em = $this->get('doctrine.orm.default_entity_manager');
$recipientId = trim($request->query->get('recipientId'));
$currentUser = $this->getCurrentUser();
//
// Get sort parameters and filter.
//
$sortingOptions = SortingOptions::fromRequest($request, 'name');
$filter = trim($request->query->get('filter'));
/** @var GroupRecipientRepository $groupRepository */
$groupRepository = $em->getRepository(GroupRecipient::class);
//
// If we got group id we should try to fetch proper recipient group and
// check that user can get this group recipient.
//
if ($recipientId !== '') {
/** @var PersonRecipientRepository $personRepository */
$personRepository = $em->getRepository(PersonRecipient::class);
$person = $personRepository->getForUser($recipientId, $currentUser->getId());
if (! $person instanceof PersonRecipient) {
return $this->generateResponse("Can't find recipient with id {$recipientId}.", 404);
}
//
// Check access.
//
$reasons = $this->checkAccess(InspectorInterface::READ, $person);
if (count($reasons) > 0) {
return $this->generateResponse($reasons, 403);
}
$statusFilter = trim($request->query->get('statusFilter', StatusFilterEnum::ALL));
if ($statusFilter !== '') {
if (! StatusFilterEnum::isValid($statusFilter)) {
return $this->generateResponse("'statusFilter' should be one of ". implode(', ', StatusFilterEnum::getAvailables()));
}
$statusFilter = new StatusFilterEnum($statusFilter);
}
$additionalCond = AdditionalConditions::fromRequest($request);
$qb = $groupRepository->getQueryBuilderForPerson(
$currentUser->getId(),
$person->getId(),
$statusFilter,
$sortingOptions,
$filter,
$additionalCond
);
} else {
$qb = $groupRepository->getQueryBuilderForUser(
$currentUser->getId(),
$sortingOptions,
$filter
);
}
//
// We should get all paginated data and put 'subscribed' field value into
// Notification entity.
//
/** @var SlidingPagination $pagination */
$pagination = $this->paginate($request, $qb);
$serializationGroups = [ 'recipient', 'id' ];
if ($recipientId !== '') {
$data = array_map(function (array $element) {
/** @var AbstractRecipient $recipient */
$recipient = $element[0];
$recipient->enrolled = (bool) $element['enrolled'];
return $recipient;
}, iterator_to_array($pagination));
$serializationGroups[] = 'sublist';
$totalCount = $pagination->getTotalItemCount();
$pagination = $this->paginate($request, $data);
$pagination->setTotalItemCount($totalCount);
}
return $this->generateResponse(
[
'groups' => $pagination,
'meta' => [ 'sort' => $sortingOptions ],
],
200,
$serializationGroups
);
}
/**
* Create new recipient group.
*
* @Roles("ROLE_MASTER_USER")
*
* @Route("", methods={ "POST" })
* @ApiDoc(
* resource="Group",
* section="Receivers",
* input={
* "class"="UserBundle\Form\GroupRecipientType",
* "name"=false
* },
* output={
* "class"="UserBundle\Entity\Recipient\GroupRecipient",
* "groups"={ "id", "recipient" }
* },
* statusCodes={
* 204="New recipient group successfully created.",
* 400="Invalid parameters."
* }
* )
*
* @param Request $request A Request instance.
*
* @return \ApiBundle\Entity\ManageableEntityInterface|\ApiBundle\Response\ViewInterface
*/
public function createAction(Request $request)
{
return parent::createEntity($request, GroupRecipient::create()->setOwner($this->getCurrentUser()));
}
/**
* Update specified recipient group.
*
* @Roles("ROLE_MASTER_USER")
*
* @Route("/{id}", methods={ "PUT" }, requirements={ "id": "\d*" })
* @ApiDoc(
* resource="Group",
* section="Receivers",
* input={
* "class"="UserBundle\Form\GroupRecipientType",
* "name"=false
* },
* output={
* "class"="UserBundle\Entity\Recipient\GroupRecipient",
* "groups"={ "id", "recipient" }
* },
* statusCodes={
* 204="Recipient group successfully updated.",
* 400="Invalid parameters."
* }
* )
*
* @param Request $request A Request instance.
* @param integer $id A GroupRecipient entity id.
*
* @return \ApiBundle\Entity\ManageableEntityInterface|\ApiBundle\Response\ViewInterface
*/
public function putAction(Request $request, $id)
{
return parent::putEntity($request, $id);
}
/**
* Delete recipient groups.
*
* @Roles("ROLE_MASTER_USER")
*
* @Route("/delete", methods={ "POST" })
* @ApiDoc(
* resource="Group",
* section="Receivers",
* input={
* "class"="",
* "data"={
* "ids"={
* "dataType"="Array of recipient group ids",
* "actualType"="collection",
* "subtype"="string",
* "required"=true,
* "readonly"=true
* }
* }
* },
* output={
* "class"="UserBundle\Entity\Recipient\GroupRecipient",
* "groups"={ "id", "recipient" }
* },
* statusCodes={
* 204="Recipient groups successfully deleted.",
* 400="Invalid parameters."
* }
* )
*
* @param Request $request A Request instance.
*
* @return \ApiBundle\Response\ViewInterface|null
*/
public function deleteAction(Request $request)
{
return $this->batchDelete($request);
}
/**
* Activate/deactivate recipient groups.
*
* @Roles("ROLE_MASTER_USER")
*
* @Route("/active", methods={ "PUT" })
* @ApiDoc(
* resource="Group",
* section="Receivers",
* input={
* "class"="",
* "data"={
* "ids"={
* "dataType"="Array of recipient groups ids",
* "actualType"="collection",
* "subtype"="string",
* "required"=true,
* "readonly"=true
* },
* "active"={
* "dataType"="Boolean flag",
* "actualType"="boolean",
* "subtype"="string",
* "required"=true,
* "readonly"=true
* }
* }
*
* },
* statusCodes={
* 204="Recipient groups successfully activated/deactivated."
* }
* )
*
* @param Request $request A Request instance.
*
* @return \ApiBundle\Response\ViewInterface
*/
public function activateAction(Request $request)
{
return $this->batchActiveToggle($request);
}
/**
* Subscribe/unsubscribe recipient from specified notifications.
*
* @Roles("ROLE_MASTER_USER")
*
* @Route("/{id}/subscribe", methods={ "PUT" })
* @ApiDoc(
* resource="Group",
* section="Receivers",
* input={
* "class"="",
* "data"={
* "ids"={
* "dataType"="Array of recipients ids",
* "actualType"="collection",
* "subtype"="string",
* "required"=true,
* "readonly"=true
* },
* "subscribe"={
* "dataType"="Boolean flag",
* "actualType"="boolean",
* "subtype"="string",
* "required"=true,
* "readonly"=true
* }
* }
*
* },
* statusCodes={
* 204="Recipient group successfully subscribed/unsubscribed."
* }
* )
*
* @param Request $request A Request instance.
* @param integer $id A PersonRecipient entity instance.
*
* @return \ApiBundle\Response\ViewInterface
*/
public function subscribeAction(Request $request, $id)
{
return $this->batchSubscriptionToggle($request, $id);
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,60 @@
<?php
namespace UserBundle\Controller\V1;
use ApiBundle\Controller\AbstractApiController;
use ApiBundle\Controller\Annotation\Roles;
use Nelmio\ApiDocBundle\Annotation\ApiDoc;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use UserBundle\Entity\Notification\NotificationTheme;
use UserBundle\Repository\NotificationThemeRepository;
/**
* Class NotificationThemeController
* @package UserBundle\Controller\V1
*
* @Route(
* "/notifications/themes",
* service="user.controller.notification_theme"
* )
*/
class NotificationThemeController extends AbstractApiController
{
/**
* Get list of all notification's for current user.
*
* @Roles("ROLE_SUBSCRIBER")
*
* @Route("/default", methods={ "GET" })
* @ApiDoc(
* resource=true,
* section="NotificationTheme",
* output={
* "class"="UserBundle\Entity\Notification\NotificationTheme",
* "groups"={ "id", "notification_theme"}
* },
* statusCodes={
* 200="Default notification successfully returned.",
* 404="Can't find default notification theme."
* }
* )
*
* @return \ApiBundle\Response\ViewInterface
*/
public function defaultAction()
{
/** @var NotificationThemeRepository $repository */
$repository = $this->getManager()->getRepository(NotificationTheme::class);
$notification = $repository->getDefault();
if (! $notification instanceof NotificationTheme) {
return $this->generateResponse('Can\'t find default notification theme', 404);
}
return $this->generateResponse($notification, 200, [
'id',
'notification_theme',
]);
}
}
@@ -0,0 +1,441 @@
<?php
namespace UserBundle\Controller\V1;
use ApiBundle\Controller\Annotation\Roles;
use ApiBundle\Response\ViewInterface;
use ApiBundle\Security\Inspector\InspectorInterface;
use AppBundle\Model\SortingOptions;
use Doctrine\ORM\EntityManagerInterface;
use Knp\Bundle\PaginatorBundle\Pagination\SlidingPagination;
use Nelmio\ApiDocBundle\Annotation\ApiDoc;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Request;
use UserBundle\Entity\Recipient\AbstractRecipient;
use UserBundle\Entity\Recipient\GroupRecipient;
use UserBundle\Entity\Recipient\PersonRecipient;
use UserBundle\Enum\StatusFilterEnum;
use UserBundle\Repository\GroupRecipientRepository;
use UserBundle\Repository\PersonRecipientRepository;
use UserBundle\Utils\AdditionalConditions;
/**
* Class PersonRecipientController
* @package UserBundle\Controller\V1
*
* @Route(
* "/recipients",
* service="user.controller.person_recipient"
* )
*/
class PersonRecipientController extends AbstractRecipientController
{
/**
* Get list of available person recipients.
*
* @Roles("ROLE_MASTER_USER")
*
* @Route("", methods={ "GET" })
* @ApiDoc(
* resource="Recipient",
* section="Receivers",
* filters={
* {
* "name"="page",
* "dataType"="integer",
* "description"="Requested page number, start from 1",
* "requirements"="\d+",
* "default"="1"
* },
* {
* "name"="limit",
* "dataType"="integer",
* "description"="Max entities per page, default 100",
* "requirements"="\d+",
* "default"="100"
* },
* {
* "name"="groupId",
* "dataType"="string",
* "description"="If set get recipients for specified recipient group",
* "requirements"="\d+",
* "required"=false
* },
* {
* "name"="sortField",
* "dataType"="string",
* "description"="Field name for sorting. Available: name, email,
* creationDate, active",
* "requirements"="\w+",
* "default"="name",
* "required"=false
* },
* {
* "name"="sortDirection",
* "dataType"="string",
* "description"="Sort direction. Available: asc, desc",
* "requirements"="(asc|desc)",
* "default"="asc",
* "required"=false
* },
* {
* "name"="filter",
* "dataType"="string",
* "description"="Keyword for searching. Part of name or email",
* "requirements"="\w+"
* },
* {
* "name"="statusFilter",
* "dataType"="string",
* "description"="Keyword for searching groups by status",
* "requirements"="(no|yes|all)"
* },
* {
* "name"="include",
* "dataType"="string",
* "description"="Comma separated list of recipient ids."
* },
* {
* "name"="exclude",
* "dataType"="string",
* "description"="Comma separated list of recipient ids."
* }
* },
* output={
* "class"="",
* "data"={
* "recipients"={
* "class"="UserBundle\Entity\Recipient\PersonRecipient",
* "groups"={ "id", "recipient" }
* },
* "meta"={
* "dataType"="model",
* "description"="Response meta information",
* "required"=true,
* "readonly"=true,
* "children"={
* "sort"={
* "dataType"="model",
* "requited"=true,
* "readonly"=true,
* "children"={
* "field"={
* "dataType"="string",
* "description"="Field name for sorting. Available:
* name, email, creationDate, active",
* "required"=true,
* "readonly"=true
* },
* "direction"={
* "dataType"="string",
* "description"="Sort direction. Available: asc,
* desc",
* "required"=true,
* "readonly"=true
* }
* }
* }
* }
* }
* }
* },
* statusCodes={
* 200="Recipients successfully funded.",
* 403="Don't has requested permissions."
* }
* )
*
* @param Request $request A Request instance.
*
* @return \ApiBundle\Response\ViewInterface
*/
public function listAction(Request $request)
{
/** @var EntityManagerInterface $em */
$em = $this->get('doctrine.orm.default_entity_manager');
$groupId = trim($request->query->get('groupId'));
$currentUser = $this->getCurrentUser();
//
// Get sort parameters and filter.
//
$sortingOptions = SortingOptions::fromRequest($request, 'name');
$filter = $request->query->get('filter', '');
/** @var PersonRecipientRepository $personRepository */
$personRepository = $em->getRepository(PersonRecipient::class);
//
// If we got group id we should try to fetch proper recipient group and
// check that user can get this group recipient.
//
if ($groupId !== '') {
/** @var GroupRecipientRepository $groupRepository */
$groupRepository = $em->getRepository(GroupRecipient::class);
$group = $groupRepository->get($groupId);
if (! $group instanceof GroupRecipient) {
return $this->generateResponse("Can't find group recipient with id {$groupId}.", 404);
}
//
// Check access.
//
$reasons = $this->checkAccess(InspectorInterface::READ, $group);
if (count($reasons) > 0) {
return $this->generateResponse($reasons, 403);
}
$statusFilter = trim($request->query->get('statusFilter', StatusFilterEnum::ALL));
if ($statusFilter !== '') {
if (! StatusFilterEnum::isValid($statusFilter)) {
return $this->generateResponse("'statusFilter' should be one of ". implode(', ', StatusFilterEnum::getAvailables()));
}
$statusFilter = new StatusFilterEnum($statusFilter);
}
$additionalCond = AdditionalConditions::fromRequest($request);
$qb = $personRepository->getQueryBuilderForGroup(
$currentUser->getId(),
$group->getId(),
$statusFilter,
$sortingOptions,
$filter,
$additionalCond
);
} else {
$qb = $personRepository->getQueryBuilderForUser(
$currentUser->getId(),
$sortingOptions,
$filter
);
}
//
// We should get all paginated data and put 'subscribed' field value into
// Notification entity.
//
/** @var SlidingPagination $pagination */
$pagination = $this->paginate($request, $qb);
$serializationGroups = [ 'recipient', 'id' ];
if ($groupId !== '') {
$data = array_map(function (array $element) {
/** @var AbstractRecipient $recipient */
$recipient = $element[0];
$recipient->enrolled = (bool) $element['enrolled'];
return $recipient;
}, iterator_to_array($pagination));
$serializationGroups[] = 'sublist';
$totalCount = $pagination->getTotalItemCount();
$pagination = $this->paginate($request, $data);
$pagination->setTotalItemCount($totalCount);
}
return $this->generateResponse(
[
'recipients' => $pagination,
'meta' => [ 'sort' => $sortingOptions ],
],
200,
$serializationGroups
);
}
/**
* Create new recipient.
*
* @Roles("ROLE_MASTER_USER")
*
* @Route("", methods={ "POST" })
* @ApiDoc(
* resource="Recipient",
* section="Receivers",
* input={
* "class"="UserBundle\Form\PersonRecipientType",
* "name"=false
* },
* output={
* "class"="UserBundle\Entity\Recipient\PersonRecipient",
* "groups"={ "id", "recipient" }
* },
* statusCodes={
* 204="New recipient successfully created.",
* 400="Invalid parameters."
* }
* )
*
* @param Request $request A Request instance.
*
* @return \ApiBundle\Response\ViewInterface
*/
public function createAction(Request $request)
{
return parent::createEntity($request, PersonRecipient::create()->setOwner($this->getCurrentUser()));
}
/**
* Update recipient.
*
* @Roles("ROLE_MASTER_USER")
*
* @Route("/{id}", methods={ "PUT" }, requirements={ "id": "\d+" })
* @ApiDoc(
* resource="Recipient",
* section="Receivers",
* input={
* "class"="UserBundle\Form\PersonRecipientType",
* "name"=false
* },
* output={
* "class"="UserBundle\Entity\Recipient\PersonRecipient",
* "groups"={ "id", "recipient" }
* },
* statusCodes={
* 200="Recipient successfully updated.",
* 400="Invalid parameters."
* }
* )
*
* @param Request $request A Request instance.
* @param integer $id A PersonRecipient entity id.
*
* @return \ApiBundle\Entity\ManageableEntityInterface|\ApiBundle\Response\ViewInterface
*/
public function putAction(Request $request, $id)
{
return parent::putEntity($request, $id);
}
/**
* Delete recipient.
*
* @Roles("ROLE_MASTER_USER")
*
* @Route("/delete", methods={ "POST" })
* @ApiDoc(
* resource="Recipient",
* section="Receivers",
* input={
* "class"="",
* "data"={
* "ids"={
* "dataType"="Array of recipients ids",
* "actualType"="collection",
* "subtype"="string",
* "required"=true,
* "readonly"=true
* }
* }
* },
* statusCodes={
* 204="Recipients successfully deleted.",
* 400="Invalid parameters."
* }
* )
*
* @param Request $request A Request instance.
*
* @return \ApiBundle\Response\ViewInterface
*/
public function deleteAction(Request $request)
{
return $this->batchDelete($request);
}
/**
* Activate/deactivate recipients.
*
* @Roles("ROLE_MASTER_USER")
*
* @Route("/active", methods={ "PUT" })
* @ApiDoc(
* resource="Recipient",
* section="Receivers",
* input={
* "class"="",
* "data"={
* "ids"={
* "dataType"="Array of recipients ids",
* "actualType"="collection",
* "subtype"="string",
* "required"=true,
* "readonly"=true
* },
* "active"={
* "dataType"="Boolean flag",
* "actualType"="boolean",
* "subtype"="string",
* "required"=true,
* "readonly"=true
* }
* }
*
* },
* statusCodes={
* 204="Recipient successfully activated/deactivated."
* }
* )
*
* @param Request $request A Request instance.
*
* @return \ApiBundle\Response\ViewInterface
*/
public function activateAction(Request $request)
{
return $this->batchActiveToggle($request);
}
/**
* Subscribe/unsubscribe recipient from specified notifications.
*
* @Roles("ROLE_MASTER_USER")
*
* @Route("/{id}/subscribe", methods={ "PUT" })
* @ApiDoc(
* resource="Recipient",
* section="Receivers",
* input={
* "class"="",
* "data"={
* "ids"={
* "dataType"="Array of recipients ids",
* "actualType"="collection",
* "subtype"="string",
* "required"=true,
* "readonly"=true
* },
* "subscribe"={
* "dataType"="Boolean flag",
* "actualType"="boolean",
* "subtype"="string",
* "required"=true,
* "readonly"=true
* }
* }
*
* },
* statusCodes={
* 204="Recipient successfully subscribed/unsubscribed."
* }
* )
*
* @param Request $request A Request instance.
* @param integer $id A PersonRecipient entity instance.
*
* @return ViewInterface
*/
public function subscribeAction(Request $request, $id)
{
return $this->batchSubscriptionToggle($request, $id);
}
}
@@ -0,0 +1,198 @@
<?php
namespace UserBundle\Controller\V1;
use ApiBundle\Controller\Annotation\Roles;
use AppBundle\Controller\Traits\TokenStorageAwareTrait;
use AppBundle\Controller\V1\AbstractV1Controller;
use AppBundle\Model\SortingOptions;
use Doctrine\ORM\EntityManagerInterface;
use Nelmio\ApiDocBundle\Annotation\ApiDoc;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use UserBundle\Entity\Notification\NotificationSendHistory;
use UserBundle\Entity\Recipient\AbstractRecipient;
use UserBundle\Enum\NotificationTypeEnum;
use UserBundle\Repository\NotificationSendHistoryRepository;
use UserBundle\Repository\RecipientRepository;
/**
* Class ReceiverController
* @package UserBundle\Controller\V1
*
* @Route(
* "/receivers",
* service="user.controller.receiver"
* )
*/
class ReceiverController extends AbstractV1Controller
{
const DEFAULT_LIMIT = 30;
use TokenStorageAwareTrait;
/**
* @var EntityManagerInterface
*/
private $em;
/**
* ReceiverController constructor.
*
* @param TokenStorageInterface $tokenStorage A TokenStorageInterface
* instance.
* @param EntityManagerInterface $em A EntityManagerInterface
* instance.
*/
public function __construct(
TokenStorageInterface $tokenStorage,
EntityManagerInterface $em
) {
$this->tokenStorage = $tokenStorage;
$this->em = $em;
}
/**
* Get list of available receivers.
*
* @Roles("ROLE_SUBSCRIBER")
*
* @Route("", methods={ "GET" })
* @ApiDoc(
* resource=true,
* section="Receivers",
* filters={
* {
* "name"="filter",
* "dataType"="string",
* "description"="Receivers name filter",
* "requirements"="[\w\s]+"
* },
* {
* "name"="exclude",
* "dataType"="string",
* "description"="Comma separated list of ids.",
* "requirements"="[\w,]+"
* }
* },
* output={
* "class"="Pagination<UserBundle\Entity\Recipient\AbstractRecipient>",
* "groups"={ "id", "recipient_autocompletion" }
* },
* statusCodes={
* 200="Receivers successfully funded."
* }
* )
*
* @param Request $request A Request instance.
*
* @return \ApiBundle\Response\ViewInterface
*/
public function listAction(Request $request)
{
$keyword = trim($request->query->get('filter'));
$exclude = array_filter(array_map('trim', explode(',', $request->query->get('exclude', ''))));
/** @var RecipientRepository $repository */
$repository = $this->em->getRepository(AbstractRecipient::class);
$recipients = $repository->search(
$this->getCurrentUser()->getId(),
self::DEFAULT_LIMIT,
$keyword,
$exclude
);
return $this->generateResponse($recipients, 200, [ 'recipient_autocompletion', 'id' ]);
}
/**
* Get email history for specified receiver.
*
* @Roles("ROLE_SUBSCRIBER")
*
* @Route("/{id}/emailHistory", methods={ "GET" }, requirements={ "id": "\d+" })
* @ApiDoc(
* resource=true,
* section="Receivers",
* filters={
* {
* "name"="page",
* "dataType"="integer",
* "description"="Requested page number, start from 1",
* "requirements"="\d+",
* "default"="1"
* },
* {
* "name"="limit",
* "dataType"="integer",
* "description"="Max entities per page, default 100",
* "requirements"="\d+",
* "default"="100"
* },
* {
* "name"="sortField",
* "dataType"="string",
* "description"="Field name for sorting. Available: name, type, scheduleTime, sentTime",
* "requirements"="\w+",
* "default"="name",
* "required"=false
* },
* {
* "name"="sortDirection",
* "dataType"="string",
* "description"="Sort direction. Available: asc, desc",
* "requirements"="(asc|desc)",
* "default"="asc",
* "required"=false
* },
* {
* "name"="typeFilter",
* "dataType"="string",
* "description"="Filter receivers by notification type of specified entity id.",
* "requirements"="(alerts|newsletter|all)",
* "default"="all",
* "required"=false
* }
* },
* output={
* "class"="Pagination<UserBundle\Entity\Notification\NotificationSendHistory>",
* "groups"={ "id", "history", "schedule" }
* },
* statusCodes={
* 200="Receivers successfully funded."
* }
* )
*
* @param Request $request A Request instance.
* @param integer $id A AbstractRecipient entity id.
*
* @return \ApiBundle\Response\ViewInterface
*/
public function historyAction(Request $request, $id)
{
$recipient = $this->em->find(AbstractRecipient::class, $id);
if (! $recipient instanceof AbstractRecipient) {
return $this->generateResponse("Can't find receiver with id {$id}.", 404);
}
$sortingOptions = SortingOptions::fromRequest($request, 'sentTime');
$typeFilter = $request->query->get('typeFilter', 'all');
if (($typeFilter !== 'all') && ! NotificationTypeEnum::isValid($typeFilter)) {
return $this->generateResponse("'typeFilter' should be one of all, ". implode(', ', NotificationTypeEnum::getAvailables()));
}
/** @var NotificationSendHistoryRepository $repository */
$repository = $this->em->getRepository(NotificationSendHistory::class);
$qb = $repository->getListForRecipient($recipient, $sortingOptions, $typeFilter);
$pagination = $this->paginate(
$qb,
$request->query->getInt('page', 1),
$request->query->getInt('limit', 10)
);
return $this->generateResponse($pagination, 200, [ 'id', 'history', 'schedule' ]);
}
}
@@ -0,0 +1,741 @@
<?php
namespace UserBundle\Controller\V1;
use ApiBundle\Controller\Annotation\Roles;
use AppBundle\Controller\Traits\FormFactoryAwareTrait;
use AppBundle\Controller\Traits\TokenStorageAwareTrait;
use AppBundle\Controller\V1\AbstractV1Controller;
use FOS\UserBundle\Model\UserManagerInterface;
use Nelmio\ApiDocBundle\Annotation\ApiDoc;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use UserBundle\Form\ChangePasswordType;
use Symfony\Component\DependencyInjection\ContainerInterface;
use PaymentBundle\Enum\PaymentGatewayEnum;
use UserBundle\Entity\Subscription\OrganizationSubscription;
use Stripe\Exception\ApiErrorException;
use UserBundle\Entity\Plan;
/**
* Class UserController
* @package UserBundle\Controller\V1
*
* @Route(
* "/users",
* service="user.controller.user"
* )
*/
class UserController extends AbstractV1Controller
{
use
TokenStorageAwareTrait,
FormFactoryAwareTrait;
/**
* @var UserManagerInterface
*/
private $userManager;
/**
* @var ContainerInterface
*/
private $container;
/**
* UserController constructor.
*
* @param TokenStorageInterface $tokenStorage A TokenStorageInterface
* instance.
* @param FormFactoryInterface $formFactory A FormFactoryInterface instance.
* @param UserManagerInterface $userManager A UserManagerInterface instance.
*/
public function __construct(
TokenStorageInterface $tokenStorage,
FormFactoryInterface $formFactory,
UserManagerInterface $userManager,
ContainerInterface $container
) {
$this->tokenStorage = $tokenStorage;
$this->formFactory = $formFactory;
$this->userManager = $userManager;
$this->container = $container;
}
/**
* Change password for current user.
*
* @Roles("ROLE_SUBSCRIBER")
*
* @Route("/change-password", methods={ "POST" })
* @ApiDoc(
* resource="Security",
* section="User",
* input={
* "class"="UserBundle\Form\ChangePasswordType",
* "name"=false
* }
* )
*
* @param Request $request A Http Request instance.
*
* @return \ApiBundle\Response\ViewInterface
*/
public function changePasswordAction(Request $request)
{
$user = $this->getCurrentUser();
$form = $this
->createForm(ChangePasswordType::class, $user)
->submit($request->request->all());
if ($form->isSubmitted() && $form->isValid()) {
$this->userManager->updateUser($user);
return $this->generateResponse();
}
return $this->generateResponse($form, 400);
}
/**
* Get list of subscriber for current master.
*
* @Roles("ROLE_SUBSCRIBER")
*
* @Route("/current/restrictions", methods={ "GET" })
* @ApiDoc(
* resource="Current",
* section="User",
* output={
* "class"="",
* "data"={
* "limits"={
* "dataType"="object",
* "required"=true,
* "readonly"=true,
* "children"={
* "searchesPerDay"={
* "dataType"="object",
* "description"="Searches per day limits",
* "required"=true,
* "readonly"=true,
* "children"={
* "limit"={
* "dataType"="integer",
* "description"="Allowed searches count",
* "required"=true,
* "readonly"=true
* },
* "current"={
* "dataType"="integer",
* "description"="Used searches count",
* "required"=true,
* "readonly"=true
* }
* }
* },
* "savedFeeds"={
* "dataType"="object",
* "description"="Feeds limits",
* "required"=true,
* "readonly"=true,
* "children"={
* "limit"={
* "dataType"="integer",
* "description"="Allowed feeds count",
* "required"=true,
* "readonly"=true
* },
* "current"={
* "dataType"="integer",
* "description"="Used feeds count",
* "required"=true,
* "readonly"=true
* }
* }
* },
* "masterAccounts"={
* "dataType"="object",
* "description"="Master accounts limits",
* "required"=true,
* "readonly"=true,
* "children"={
* "limit"={
* "dataType"="integer",
* "description"="Allowed master accounts count",
* "required"=true,
* "readonly"=true
* },
* "current"={
* "dataType"="integer",
* "description"="Used master accounts count",
* "required"=true,
* "readonly"=true
* }
* }
* },
* "subscriberAccounts"={
* "dataType"="object",
* "description"="Subscriber accounts limits",
* "required"=true,
* "readonly"=true,
* "children"={
* "limit"={
* "dataType"="integer",
* "description"="Allowed subscriber accounts count",
* "required"=true,
* "readonly"=true
* },
* "current"={
* "dataType"="integer",
* "description"="Used subscriber accounts count",
* "required"=true,
* "readonly"=true
* }
* }
* },
* "alerts"={
* "dataType"="object",
* "description"="Alerts limits",
* "required"=true,
* "readonly"=true,
* "children"={
* "limit"={
* "dataType"="integer",
* "description"="Allowed alerts count",
* "required"=true,
* "readonly"=true
* },
* "current"={
* "dataType"="integer",
* "description"="Used alerts count",
* "required"=true,
* "readonly"=true
* }
* }
* },
* "newsletters"={
* "dataType"="object",
* "description"="Newsletters limits",
* "required"=true,
* "readonly"=true,
* "children"={
* "limit"={
* "dataType"="integer",
* "description"="Allowed newsletters count",
* "required"=true,
* "readonly"=true
* },
* "current"={
* "dataType"="integer",
* "description"="Used newsletters count",
* "required"=true,
* "readonly"=true
* }
* }
* }
*
* }
* },
* "permissions"={
* "dataType"="object",
* "required"=true,
* "readonly"=true,
* "children"={
* "analytics"={
* "dataType"="boolean",
* "description"="Can user use analytics or not",
* "required"=true,
* "readonly"=true
* }
* }
* }
* }
* },
* statusCodes={
* 200="List of restrictions successfully returned."
* }
* )
*
* @return \ApiBundle\Response\ViewInterface
*/
public function restrictionsAction()
{
$user = $this->getCurrentUser();
if ($user === null) {
return $this->generateResponse([], 403);
}
return $this->generateResponse($user->getRestrictions());
}
/**
*
* @Route("/update/plan", methods={ "POST" })
*
* @param Request $request A Http Request instance.
*/
public function updatePlanAction(Request $request)
{
$user = $this->getCurrentUser();
$data = $request->request->all();
$gateway = PaymentGatewayEnum::paypal();
$em = $this->container->get('doctrine.orm.default_entity_manager');
if (isset(
$data['news'],
$data['blog'],
$data['reddit'],
$data['instagram'],
$data['twitter'],
$data['analytics'],
$data['searchesPerDay'],
$data['savedFeeds'],
$data['masterAccounts'],
$data['subscriberAccounts'],
$data['webFeeds'],
$data['alerts']
) &&
($data['searchesPerDay'] >= 0) &&
($data['savedFeeds'] >= 0) &&
($data['masterAccounts'] >= 0) &&
($data['subscriberAccounts'] >= 0) &&
($data['webFeeds'] >= 0) &&
($data['alerts'] >= 0)
) {
//Call cost calculation plan
$costCalculation = $this->container->get('cost.calculation');
$response = $costCalculation->costCalculationAction($request, true);
$oldPrice = $user->getBillingSubscription()->getPlan()->getPrice();
//Stripe process
$stripe = $this->container->get('stripe.service');
$stripe->setApiKey();
if (empty($user->getStripeUserId())) {
$customer = $stripe->createCustomer(
[
'email' => $user->getEmail(),
'name' => $user->getFirstName().' '.$user->getLastName(),
'metadata' => ['paymentMethod' => $data['paymentID']]
]
);
$customerArray = [];
if ($customer instanceof ApiErrorException) {
$customerArray = ['paymentError' => 1,'data'=>$customer,'message'=>'Customer failed'];
return $this->generateResponse($customerArray, 400);
}
if (isset($customer['id'])) {
$user->setStripeUserId($customer['id']);
$em->persist($user);
$em->flush();
//Add card atatch to customer
if (isset($data['paymentID']) && !empty($data['paymentID'])) {
$cardAttach = $stripe->paymentMethodAttachToCustomer($data['paymentID'],
['customer' => $customer['id']]
);
if ($cardAttach instanceof ApiErrorException) {
$cardAttachArray = ['paymentError' => 1,'data'=>$cardAttach,'message'=>'Card attached to customer failed'];
return $this->generateResponse($cardAttachArray, 500);
}
}
//Add product
$product = $stripe->addProduct(
[
'name' => $user->getCompanyName(),
'metadata' => (array)$customer['id']
]
);
if ($product instanceof ApiErrorException) {
$productArray = ['paymentError' => 1,'data'=>$product,'message'=>'Product failed'];
return $this->generateResponse($productArray, 400);
}
if (isset($product['id'])) {
//Call cost calculation plan
$costCalculation = $this->container->get('cost.calculation');
$response = $costCalculation->costCalculationAction($request, true);
$price = $stripe->addPrice(
[
'unit_amount' => isset($response['price']) ? $response['price'] * 100 : 0,
'currency' => 'usd',
'recurring' => ['interval' => 'month'],
'product' => $product['id']
]
);
if ($price instanceof ApiErrorException) {
$priceArray = ['paymentError' => 1,'data'=>$price,'message'=>'Price add failed'];
return $this->generateResponse($priceArray, 400);
}
//Plan subscription code
if (isset($price['id'])) {
//Add plan
$subscription = $stripe->createSubscription(
[
'customer' => $customer['id'],
'items' => [['price' => $price['id']]],
'default_payment_method' => $data['paymentID']
]
);
if ($subscription instanceof ApiErrorException) {
$subscriptionArray = ['paymentError' => 1,'data'=>$subscription,'message'=>'Subscribtion failed'];
return $this->generateResponse($subscriptionArray, 400);
}
//update customer metadata
$customer = $stripe->updateCustomer($customer['id'],
[
'metadata' => [
'paymentMethod' => $data['paymentID'],
'productId' => $product['id'],
'priceId' => $price['id'],
'subscriptionId' => $subscription['id'],
'subStartDate' => $subscription['current_period_start'],
'subEndDate' => $subscription['current_period_end'],
]
]
);
$customerArray = [];
if ($customer instanceof ApiErrorException) {
$customerArray = ['paymentError' => 1,'data'=>$customer,'message'=>'Customer add meta data failed'];
return $this->generateResponse($customerArray, 400);
}
$plan = $user->getBillingSubscription()->getPlan();
$plan->setTitle($user->getCompanyName())
->setInnerName('Starter')
->setPrice(isset($response['price']) ? $response['price'] : 0)
->setNews($data['news'])
->setBlog($data['blog'])
->setReddit($data['reddit'])
->setInstagram($data['instagram'])
->setTwitter($data['twitter'])
->setAnalytics($data['analytics'])
->setSearchesPerDay($data['searchesPerDay'])
->setSavedFeeds($data['savedFeeds'])
->setMasterAccounts($data['masterAccounts'])
->setSubscriberAccounts($data['subscriberAccounts'])
->setWebFeeds($data['webFeeds'])
->setUser($user)
->setAlerts($data['alerts']);
$em->persist($plan);
$em->flush();
$subscriptionObj = $user->getBillingSubscription();
$subscriptionObj->setGateway($gateway);
$subscriptionObj->setStartDate(new \DateTime('@' . $subscription['current_period_start']));
$subscriptionObj->setEndDate(new \DateTime('@' . $subscription['current_period_end']));
$em->persist($subscriptionObj);
$em->flush();
}
}
}
} else {
if ($response['price'] < $oldPrice) {
$planNew = new Plan();
$planNew->setTitle($user->getCompanyName());
$planNew->setInnerName('Starter');
$planNew->setPrice(isset($response['price']) ? $response['price'] : 0);
$planNew->setNews($data['news']);
$planNew->setBlog($data['blog']);
$planNew->setReddit($data['reddit']);
$planNew->setInstagram($data['instagram']);
$planNew->setTwitter($data['twitter']);
$planNew->setAnalytics($data['analytics']);
$planNew->setSearchesPerDay($data['searchesPerDay']);
$planNew->setSavedFeeds($data['savedFeeds']);
$planNew->setMasterAccounts($data['masterAccounts']);
$planNew->setSubscriberAccounts($data['subscriberAccounts']);
$planNew->setWebFeeds($data['webFeeds']);
$planNew->setAlerts($data['alerts']);
$planNew->setUser($user);
$planNew->setIsPlanDowngrade(true);
$em->persist($planNew);
$em->flush();
$subscription = $user->getBillingSubscription();
$subscription->setIsPlanDowngrade(true);
$em->persist($subscription);
$em->flush();
$customer = $stripe->getCustomer(
$user->getStripeUserId()
);
$customerArray = [];
if ($customer instanceof ApiErrorException) {
$customerArray = ['paymentError' => 1,'data'=>$customer,'message'=>'Customer not found'];
return $this->generateResponse($customerArray, 400);
}
if (isset($customer['id']) && isset($data['paymentID']) && !empty($data['paymentID'])) {
//Add card atatch to customer
$cardAttach = $stripe->paymentMethodAttachToCustomer($data['paymentID'],
['customer' => $customer['id']]
);
if ($cardAttach instanceof ApiErrorException) {
$cardAttachArray = ['paymentError' => 1,'data'=>$cardAttach,'message'=>'Card update attached to customer failed'];
return $this->generateResponse($cardAttachArray, 500);
}
//Card detach to customer
$cardDetachPaymentMethod = $stripe->paymentMethodDetachToCustomer($customer['metadata']['paymentMethod']
);
if ($cardDetachPaymentMethod instanceof ApiErrorException) {
$cardDetachArray = ['paymentError' => 1,'data'=>$cardDetachPaymentMethod,'message'=>'Card detach to customer failed'];
return $this->generateResponse($cardDetachArray, 500);
}
//update customer metadata
$customer = $stripe->updateCustomer($customer['id'],
[
'metadata' => [
'paymentMethod' => isset($data['paymentID']) ? $data['paymentID'] : $customer['metadata']['paymentMethod'],
]
]
);
$customerArray = [];
if ($customer instanceof ApiErrorException) {
$customerArray = ['paymentError' => 1,'data'=>$customer,'message'=>'Customer update meta data failed'];
return $this->generateResponse($customerArray, 400);
}
}
} else {
$customer = $stripe->getCustomer(
$user->getStripeUserId()
);
$customerArray = [];
if ($customer instanceof ApiErrorException) {
$customerArray = ['paymentError' => 1,'data'=>$customer,'message'=>'Customer not found'];
return $this->generateResponse($customerArray, 400);
}
if (isset($customer['id'])) {
//Add card atatch to customer
if (isset($data['paymentID']) && !empty($data['paymentID'])) {
$cardAttach = $stripe->paymentMethodAttachToCustomer($data['paymentID'],
['customer' => $customer['id']]
);
if ($cardAttach instanceof ApiErrorException) {
$cardAttachArray = ['paymentError' => 1,'data'=>$cardAttach,'message'=>'Card update attached to customer failed'];
return $this->generateResponse($cardAttachArray, 500);
}
//Card detach to customer
$cardDetachPaymentMethod = $stripe->paymentMethodDetachToCustomer($customer['metadata']['paymentMethod']
);
if ($cardDetachPaymentMethod instanceof ApiErrorException) {
$cardDetachArray = ['paymentError' => 1,'data'=>$cardDetachPaymentMethod,'message'=>'Card detach to customer failed'];
return $this->generateResponse($cardDetachArray, 500);
}
}
if (isset($customer['metadata']['productId'])) {
$price = $stripe->addPrice(
[
'unit_amount' => isset($response['price']) ? $response['price'] * 100 : 0,
'currency' => 'usd',
'recurring' => ['interval' => 'month'],
'product' => $customer['metadata']['productId']
]
);
if ($price instanceof ApiErrorException) {
$priceArray = ['paymentError' => 1,'data'=>$price,'message'=>'Price not found'];
return $this->generateResponse($priceArray, 400);
}
//Plan subscription code
if (isset($price['id'])) {
//Add subscription
$subscription = $stripe->getSubscription(
$customer['metadata']['subscriptionId']
);
if ($subscription instanceof ApiErrorException) {
$subscriptionArray = ['paymentError' => 1,'data'=>$subscription,'message'=>'Subscribtion get failed'];
return $this->generateResponse($subscriptionArray, 400);
}
if (isset($subscription['id'])) {
//Add subscription item
$subscriptionItem = $stripe->updateSubscriptionItem($subscription['items']['data'][0]['id'],
[
'price' => $price['id'],
]
);
if ($subscriptionItem instanceof ApiErrorException) {
$subscriptionItemArray = ['paymentError' => 1,'data'=>$subscriptionItem,'message'=>'Subscribtion Item failed'];
return $this->generateResponse($subscriptionItemArray, 400);
}
}
//update customer metadata
$customer = $stripe->updateCustomer($customer['id'],
[
'metadata' => [
'paymentMethod' => isset($data['paymentID']) ? $data['paymentID'] : $customer['metadata']['paymentMethod'],
'priceId' => $price['id'],
'subscriptionId' => $subscription['id'],
'subStartDate' => $subscription['current_period_start'],
'subEndDate' => $subscription['current_period_end'],
]
]
);
$customerArray = [];
if ($customer instanceof ApiErrorException) {
$customerArray = ['paymentError' => 1,'data'=>$customer,'message'=>'Customer update meta data failed'];
return $this->generateResponse($customerArray, 400);
}
$plan = $user->getBillingSubscription()->getPlan();
$plan->setTitle($user->getCompanyName())
->setInnerName('Starter')
->setPrice(isset($response['price']) ? $response['price'] : 0)
->setNews($data['news'])
->setBlog($data['blog'])
->setReddit($data['reddit'])
->setInstagram($data['instagram'])
->setTwitter($data['twitter'])
->setAnalytics($data['analytics'])
->setSearchesPerDay($data['searchesPerDay'])
->setSavedFeeds($data['savedFeeds'])
->setMasterAccounts($data['masterAccounts'])
->setSubscriberAccounts($data['subscriberAccounts'])
->setWebFeeds($data['webFeeds'])
->setUser($user)
->setAlerts($data['alerts']);
$em->persist($plan);
$em->flush();
$user->getBillingSubscription()->setStartDate(new \DateTime('@' . $subscription['current_period_start']));
$user->getBillingSubscription()->setEndDate(new \DateTime('@' . $subscription['current_period_end']));
$em->persist($user);
$em->flush();
}
}
}
}
}
}
return $this->generateResponse([
'success' => true,
]);
}
/**
*
* @Route("/cancel/plan", methods={ "POST" })
*
* @param Request $request A Http Request instance.
*/
public function cancelSubscriptionAction(Request $request)
{
$user = $this->getCurrentUser();
//Stripe process
$stripe = $this->container->get('stripe.service');
$stripe->setApiKey();
$em = $this->container->get('doctrine.orm.default_entity_manager');
$customer = $stripe->getCustomer(
$user->getStripeUserId()
);
$customerArray = [];
if ($customer instanceof ApiErrorException) {
$customerArray = ['paymentError' => 1,'data'=>$customer,'message'=>'Customer not found'];
return $this->generateResponse($customerArray, 400);
}
if (isset($customer['id'])) {
$updateSubscription = $stripe->updateSubscription($customer['metadata']['subscriptionId'],
[
'cancel_at_period_end' => true,
]
);
if ($updateSubscription instanceof ApiErrorException) {
$updateSubscriptionArray = ['paymentError' => 1,'data'=>$updateSubscription,'message'=>'Cancel subscription'];
return $this->generateResponse($updateSubscriptionArray, 500);
}
$user->getBillingSubscription()->setIsSubscriptionCancelled(true);
$em->persist($user);
$em->flush();
}
return $this->generateResponse([
'success' => true,
]);
}
/**
*
* @Route("/card/change", methods={ "POST" })
*
* @param Request $request A Http Request instance.
*/
public function changeCardAction(Request $request)
{
$user = $this->getCurrentUser();
if (!empty($user->getStripeUserId())) {
$customerStripeId = $user->getStripeUserId();
$stripe = $this->container->get('stripe.service');
$stripe->setApiKey();
$customer = $stripe->getCustomer(
$user->getStripeUserId()
);
//Card detach to customer
$cardDetachPaymentMethod = $stripe->paymentMethodDetachToCustomer($customer['metadata']['paymentMethod']
);
if ($cardDetachPaymentMethod instanceof ApiErrorException) {
$cardDetachArray = ['paymentError' => 1,'data'=>$cardDetachPaymentMethod,'message'=>'Card detach to customer failed'];
return $this->generateResponse($cardDetachArray, 500);
}
//Card attach to customer
$cardAttachPaymentMethod = $stripe->paymentMethodAttachToCustomer($request->request->get('paymentID'),
['customer' => $customerStripeId]
);
if ($cardAttachPaymentMethod instanceof ApiErrorException) {
$cardAttachArray = ['paymentError' => 1,'data'=>$cardAttachPaymentMethod,'message'=>'Updated card attached to customer failed'];
return $this->generateResponse($cardAttachArray, 500);
}
//update customer metadata
$customer = $stripe->updateCustomer($customerStripeId,
[
'metadata' => ['paymentMethod' => $request->request->get('paymentID')]
]
);
if ($customer instanceof ApiErrorException) {
$customerArray = ['paymentError' => 1,'data'=>$customer,'message'=>'Customer update meta data failed'];
return $this->generateResponse($customerArray, 400);
}
$data = ['success' => 1,'message'=>'Card updated successfully to this customer..'];
return $this->generateResponse($data,200);
}
$data = ['error' => 1,'message'=>'Customer not registered in Stripe'];
return $this->generateResponse($data, 400);
}
/**
*
* @Route("/invoices", methods={ "GET" })
*
* @param Request $request A Http Request instance.
*/
public function getInvoiceAction(Request $request)
{
$user = $this->getCurrentUser();
$invoices = [];
if (!empty($user->getStripeUserId())) {
$stripe = $this->container->get('stripe.service');
$stripe->setApiKey();
$invoices = $stripe->getAllInvoice(['customer' => $user->getStripeUserId()]);
if ($invoices instanceof ApiErrorException) {
$invoicesArray = ['paymentError' => 1,'data'=>$invoices,'message'=>'List all invoice of customer faild'];
return $this->generateResponse($invoicesArray, 400);
}
}
$data = ['success' => 1,'data' => $invoices];
return $this->generateResponse($data, 200);
}
}