diff --git a/assets/js/src/forms/list.jsx b/assets/js/src/forms/list.jsx index 7d2e54c761..9d88b18960 100644 --- a/assets/js/src/forms/list.jsx +++ b/assets/js/src/forms/list.jsx @@ -182,6 +182,30 @@ class FormList extends React.Component { } }; + updateStatus = (e) => { + // make the event persist so that we can still override the selected value + // in the ajax callback + e.persist(); + + MailPoet.Ajax.post({ + api_version: window.mailpoet_api_version, + endpoint: 'forms', + action: 'setStatus', + data: { + id: Number(e.target.getAttribute('data-id')), + status: e.target.value, + }, + }).done((response) => { + if (response.data.status === 'enabled') { + MailPoet.Notice.success(MailPoet.I18n.t('formActivated')); + } + }).fail((response) => { + MailPoet.Notice.showApiErrorNotice(response); + + // reset value to actual newsletter's status + e.target.value = response.status; + }); + }; renderStatus(form) { return ( diff --git a/lib/API/JSON/v1/Forms.php b/lib/API/JSON/v1/Forms.php index 94b419539e..a3a987dae7 100644 --- a/lib/API/JSON/v1/Forms.php +++ b/lib/API/JSON/v1/Forms.php @@ -8,6 +8,7 @@ use MailPoet\Config\AccessControl; use MailPoet\Entities\FormEntity; use MailPoet\Form\DisplayFormInWPContent; use MailPoet\Form\FormFactory; +use MailPoet\Form\FormsRepository; use MailPoet\Form\PreviewPage; use MailPoet\Form\Util; use MailPoet\Listing; @@ -18,6 +19,11 @@ use MailPoet\WP\Functions as WPFunctions; class Forms extends APIEndpoint { + + public $permissions = [ + 'global' => AccessControl::PERMISSION_MANAGE_FORMS, + ]; + /** @var Listing\BulkActionController */ private $bulkAction; @@ -33,15 +39,15 @@ class Forms extends APIEndpoint { /** @var WPFunctions */ private $wp; - public $permissions = [ - 'global' => AccessControl::PERMISSION_MANAGE_FORMS, - ]; + /** @var FormsRepository */ + private $formsRepository; public function __construct( Listing\BulkActionController $bulkAction, Listing\Handler $listingHandler, UserFlagsController $userFlags, FormFactory $formFactory, + FormsRepository $formsRepository, WPFunctions $wp ) { $this->bulkAction = $bulkAction; @@ -49,6 +55,7 @@ class Forms extends APIEndpoint { $this->userFlags = $userFlags; $this->formFactory = $formFactory; $this->wp = $wp; + $this->formsRepository = $formsRepository; } public function get($data = []) { @@ -62,6 +69,45 @@ class Forms extends APIEndpoint { ]); } + public function setStatus($data = []) { + $status = (isset($data['status']) ? $data['status'] : null); + + if (!$status) { + return $this->badRequest([ + APIError::BAD_REQUEST => __('You need to specify a status.', 'mailpoet'), + ]); + } + + $id = (isset($data['id'])) ? (int)$data['id'] : false; + $form = $this->formsRepository->findOneById($id); + + if (!$form instanceof FormEntity) { + return $this->errorResponse([ + APIError::NOT_FOUND => __('This form does not exist.', 'mailpoet'), + ]); + } + + if (!in_array($status, [FormEntity::STATUS_ENABLED, FormEntity::STATUS_DISABLED])) { + return $this->badRequest([ + APIError::BAD_REQUEST => + sprintf( + __('Invalid status. Allowed values are (%1$s), you specified %2$s', 'mailpoet'), + join(', ', [FormEntity::STATUS_ENABLED, FormEntity::STATUS_DISABLED]), + $status + ), + ]); + } + + $form->setStatus($status); + $this->formsRepository->flush(); + + $form = $this->formsRepository->findOneById($id); + if (!$form instanceof FormEntity) return $this->errorResponse(); + return $this->successResponse( + $form->toArray() + ); + } + public function listing($data = []) { $data['sort_order'] = $data['sort_order'] ?? 'desc'; $data['sort_by'] = $data['sort_by'] ?? 'updated_at'; diff --git a/lib/Entities/FormEntity.php b/lib/Entities/FormEntity.php index bfbe017042..6ee1ed6f05 100644 --- a/lib/Entities/FormEntity.php +++ b/lib/Entities/FormEntity.php @@ -125,6 +125,13 @@ class FormEntity { $this->status = $status; } + /** + * @return string + */ + public function getStatus(): string { + return $this->status; + } + public function toArray(): array { return [ 'id' => $this->getId(), @@ -132,6 +139,7 @@ class FormEntity { 'body' => $this->getBody(), 'settings' => $this->getSettings(), 'styles' => $this->getStyles(), + 'status' => $this->getStatus(), 'created_at' => $this->getCreatedAt(), 'updated_at' => $this->getUpdatedAt(), 'deleted_at' => $this->getDeletedAt(), diff --git a/lib/Models/Form.php b/lib/Models/Form.php index f3235ec465..ddf6125dac 100644 --- a/lib/Models/Form.php +++ b/lib/Models/Form.php @@ -9,6 +9,7 @@ use MailPoet\WP\Functions as WPFunctions; * @property string|array $settings * @property string|array $body * @property string $name + * @property string $status */ class Form extends Model { diff --git a/tests/integration/API/JSON/v1/FormsTest.php b/tests/integration/API/JSON/v1/FormsTest.php index f123e9df92..aa8c714a8f 100644 --- a/tests/integration/API/JSON/v1/FormsTest.php +++ b/tests/integration/API/JSON/v1/FormsTest.php @@ -5,6 +5,7 @@ namespace MailPoet\Test\API\JSON\v1; use MailPoet\API\JSON\Response as APIResponse; use MailPoet\API\JSON\v1\Forms; use MailPoet\DI\ContainerWrapper; +use MailPoet\Entities\FormEntity; use MailPoet\Form\PreviewPage; use MailPoet\Models\Form; use MailPoet\Models\Segment; @@ -177,6 +178,43 @@ class FormsTest extends \MailPoetTest { expect($response->meta['count'])->equals(0); } + public function testItCanUpdateFormStatus() { + $response = $this->endpoint->setStatus([ + 'status' => FormEntity::STATUS_ENABLED, + 'id' => $this->form1->id, + ]); + expect($response->status)->equals(APIResponse::STATUS_OK); + $form = Form::findOne($this->form1->id); + assert($form instanceof Form); + expect($form->status)->equals(FormEntity::STATUS_ENABLED); + + $response = $this->endpoint->setStatus([ + 'status' => FormEntity::STATUS_DISABLED, + 'id' => $this->form1->id, + ]); + expect($response->status)->equals(APIResponse::STATUS_OK); + $form = Form::findOne($this->form1->id); + assert($form instanceof Form); + expect($form->status)->equals(FormEntity::STATUS_DISABLED); + + $response = $this->endpoint->setStatus([ + 'status' => FormEntity::STATUS_DISABLED, + 'id' => 'invalid id', + ]); + expect($response->status)->equals(APIResponse::STATUS_NOT_FOUND); + + $response = $this->endpoint->setStatus([ + 'id' => $this->form1->id, + ]); + expect($response->status)->equals(APIResponse::STATUS_BAD_REQUEST); + + $response = $this->endpoint->setStatus([ + 'status' => 'invalid status', + 'id' => $this->form1->id, + ]); + expect($response->status)->equals(APIResponse::STATUS_BAD_REQUEST); + } + public function _after() { Form::deleteMany(); Segment::deleteMany(); diff --git a/views/forms.html b/views/forms.html index ea7fdefdcf..de8ef8cc06 100644 --- a/views/forms.html +++ b/views/forms.html @@ -65,6 +65,8 @@ 'status': __('Status'), 'active': __('Active'), 'inactive': __('Not Active'), + 'formActivated': __('Your Form is now activated!'), + 'previousPage': __('Previous page'), 'firstPage': __('First page'), 'nextPage': __('Next page'),