diff --git a/lib/API/JSON/ResponseBuilders/NewslettersResponseBuilder.php b/lib/API/JSON/ResponseBuilders/NewslettersResponseBuilder.php new file mode 100644 index 0000000000..b262952b20 --- /dev/null +++ b/lib/API/JSON/ResponseBuilders/NewslettersResponseBuilder.php @@ -0,0 +1,93 @@ + (string)$newsletter->getId(), // (string) for BC + 'hash' => $newsletter->getHash(), + 'subject' => $newsletter->getSubject(), + 'type' => $newsletter->getType(), + 'sender_address' => $newsletter->getSenderAddress(), + 'sender_name' => $newsletter->getSenderName(), + 'status' => $newsletter->getStatus(), + 'reply_to_address' => $newsletter->getReplyToAddress(), + 'reply_to_name' => $newsletter->getReplyToName(), + 'preheader' => $newsletter->getPreheader(), + 'body' => $newsletter->getBody(), + 'sent_at' => ($sent_at = $newsletter->getSentAt()) ? $sent_at->format(self::DATE_FORMAT) : null, + 'created_at' => $newsletter->getCreatedAt()->format(self::DATE_FORMAT), + 'updated_at' => $newsletter->getUpdatedAt()->format(self::DATE_FORMAT), + 'deleted_at' => ($deleted_at = $newsletter->getDeletedAt()) ? $deleted_at->format(self::DATE_FORMAT) : null, + 'parent_id' => ($parent = $newsletter->getParent()) ? $parent->getId() : null, + 'segments' => $this->buildSegments($newsletter), + 'options' => $this->buildOptions($newsletter), + 'queue' => ($queue = $newsletter->getQueue()) ? $this->buildQueue($queue) : false, // false for BC + 'unsubscribe_token' => $newsletter->getUnsubscribeToken(), + ]; + } + + private function buildSegments(NewsletterEntity $newsletter) { + $output = []; + foreach ($newsletter->getNewsletterSegments() as $newsletter_segment) { + $segment = $newsletter_segment->getSegment(); + if ($segment->getDeletedAt()) { + continue; + } + $output[] = $this->buildSegment($segment); + } + return $output; + } + + private function buildOptions(NewsletterEntity $newsletter) { + $output = []; + foreach ($newsletter->getOptions() as $option) { + $output[$option->getOptionField()->getName()] = $option->getValue(); + } + return $output; + } + + private function buildSegment(SegmentEntity $segment) { + return [ + 'id' => (string)$segment->getId(), // (string) for BC + 'name' => $segment->getName(), + 'type' => $segment->getType(), + 'description' => $segment->getDescription(), + 'created_at' => $segment->getCreatedAt()->format(self::DATE_FORMAT), + 'updated_at' => $segment->getUpdatedAt()->format(self::DATE_FORMAT), + 'deleted_at' => ($deleted_at = $segment->getDeletedAt()) ? $deleted_at->format(self::DATE_FORMAT) : null, + ]; + } + + private function buildQueue(SendingQueueEntity $queue) { + $task = $queue->getTask(); + + // the following crazy mix of '$queue' and '$task' comes from 'array_merge($task, $queue)' + // (MailPoet\Tasks\Sending) which means all equal-named fields will be taken from '$queue' + return [ + 'id' => (string)$queue->getId(), // (string) for BC + 'type' => $task->getType(), + 'status' => $task->getStatus(), + 'priority' => (string)$task->getPriority(), // (string) for BC + 'scheduled_at' => ($scheduled_at = $task->getScheduledAt()) ? $scheduled_at->format(self::DATE_FORMAT) : null, + 'processed_at' => ($processed_at = $task->getProcessedAt()) ? $processed_at->format(self::DATE_FORMAT) : null, + 'created_at' => $queue->getCreatedAt()->format(self::DATE_FORMAT), + 'updated_at' => $queue->getUpdatedAt()->format(self::DATE_FORMAT), + 'deleted_at' => ($deleted_at = $queue->getDeletedAt()) ? $deleted_at->format(self::DATE_FORMAT) : null, + 'meta' => $queue->getMeta(), + 'task_id' => (string)$queue->getTask()->getId(), // (string) for BC + 'newsletter_id' => (string)$queue->getNewsletter()->getId(), // (string) for BC + 'newsletter_rendered_subject' => $queue->getNewsletterRenderedSubject(), + 'count_total' => (string)$queue->getCountTotal(), // (string) for BC + 'count_processed' => (string)$queue->getCountProcessed(), // (string) for BC + 'count_to_process' => (string)$queue->getCountToProcess(), // (string) for BC + ]; + } +} diff --git a/lib/API/JSON/v1/Newsletters.php b/lib/API/JSON/v1/Newsletters.php index 43791f46b2..71066266a4 100644 --- a/lib/API/JSON/v1/Newsletters.php +++ b/lib/API/JSON/v1/Newsletters.php @@ -5,6 +5,7 @@ namespace MailPoet\API\JSON\v1; use Carbon\Carbon; use MailPoet\API\JSON\Endpoint as APIEndpoint; use MailPoet\API\JSON\Error as APIError; +use MailPoet\API\JSON\ResponseBuilders\NewslettersResponseBuilder; use MailPoet\Config\AccessControl; use MailPoet\Cron\CronHelper; use MailPoet\Cron\Workers\SendingQueue\Tasks\Newsletter as NewsletterQueueTask; @@ -17,6 +18,7 @@ use MailPoet\Models\NewsletterTemplate; use MailPoet\Models\SendingQueue; use MailPoet\Models\Setting; use MailPoet\Models\Subscriber; +use MailPoet\Newsletter\NewslettersRepository; use MailPoet\Newsletter\Renderer\Renderer; use MailPoet\Newsletter\Scheduler\Scheduler; use MailPoet\Newsletter\Url as NewsletterUrl; @@ -51,13 +53,21 @@ class Newsletters extends APIEndpoint { 'global' => AccessControl::PERMISSION_MANAGE_EMAILS, ]; + /** @var NewslettersRepository */ + private $newsletters_repository; + + /** @var NewslettersResponseBuilder */ + private $newsletters_response_builder; + function __construct( Listing\BulkActionController $bulk_action, Listing\Handler $listing_handler, WPFunctions $wp, WCHelper $woocommerce_helper, SettingsController $settings, - AuthorizedEmailsController $authorized_emails_controller + AuthorizedEmailsController $authorized_emails_controller, + NewslettersRepository $newsletters_repository, + NewslettersResponseBuilder $newsletters_response_builder ) { $this->bulk_action = $bulk_action; $this->listing_handler = $listing_handler; @@ -65,25 +75,28 @@ class Newsletters extends APIEndpoint { $this->woocommerce_helper = $woocommerce_helper; $this->settings = $settings; $this->authorized_emails_controller = $authorized_emails_controller; + $this->newsletters_repository = $newsletters_repository; + $this->newsletters_response_builder = $newsletters_response_builder; } function get($data = []) { - $id = (isset($data['id']) ? (int)$data['id'] : false); - $newsletter = Newsletter::findOne($id); - if ($newsletter instanceof Newsletter) { - $newsletter = $newsletter - ->withSegments() - ->withOptions() - ->withSendingQueue(); + $newsletter = isset($data['id']) + ? $this->newsletters_repository->findOneById((int)$data['id']) + : null; + if ($newsletter) { + $response = $this->newsletters_response_builder->build($newsletter); $preview_url = NewsletterUrl::getViewInBrowserUrl( NewsletterUrl::TYPE_LISTING_EDITOR, - $newsletter, + (object)[ + 'id' => $newsletter->getId(), + 'hash' => $newsletter->getHash(), + ], Subscriber::getCurrentWPUser() ); - $newsletter = $this->wp->applyFilters('mailpoet_api_newsletters_get_after', $newsletter->asArray()); - return $this->successResponse($newsletter, ['preview_url' => $preview_url]); + $response = $this->wp->applyFilters('mailpoet_api_newsletters_get_after', $response); + return $this->successResponse($response, ['preview_url' => $preview_url]); } else { return $this->errorResponse([ APIError::NOT_FOUND => WPFunctions::get()->__('This email does not exist.', 'mailpoet'), diff --git a/lib/DI/ContainerConfigurator.php b/lib/DI/ContainerConfigurator.php index 1e9d6d91ed..131fdbcf6f 100644 --- a/lib/DI/ContainerConfigurator.php +++ b/lib/DI/ContainerConfigurator.php @@ -75,6 +75,8 @@ class ContainerConfigurator implements IContainerConfigurator { $container->autowire(\MailPoet\API\JSON\v1\SendingTaskSubscribers::class)->setPublic(true); $container->autowire(\MailPoet\API\JSON\v1\Setup::class)->setPublic(true); $container->autowire(\MailPoet\API\JSON\v1\Subscribers::class)->setPublic(true); + // API response builders + $container->autowire(\MailPoet\API\JSON\ResponseBuilders\NewslettersResponseBuilder::class); // Config $container->autowire(\MailPoet\Config\AccessControl::class)->setPublic(true); $container->autowire(\MailPoet\Config\Activator::class)->setPublic(true); @@ -174,6 +176,7 @@ class ContainerConfigurator implements IContainerConfigurator { $container->autowire(\MailPoet\Subscription\Registration::class)->setPublic(true); // Newsletter $container->autowire(\MailPoet\Newsletter\AutomatedLatestContent::class)->setPublic(true); + $container->autowire(\MailPoet\Newsletter\NewslettersRepository::class); // Util $container->autowire(\MailPoet\Util\Cookies::class); $container->autowire(\MailPoet\Util\Url::class)->setPublic(true); diff --git a/lib/Newsletter/NewslettersRepository.php b/lib/Newsletter/NewslettersRepository.php new file mode 100644 index 0000000000..38fc07fa35 --- /dev/null +++ b/lib/Newsletter/NewslettersRepository.php @@ -0,0 +1,19 @@ +makeEmpty(WCHelper::class), new SettingsController(), - $this->make(AuthorizedEmailsController::class, ['onNewsletterUpdate' => Expected::never()]) + $this->make(AuthorizedEmailsController::class, ['onNewsletterUpdate' => Expected::never()]), + ContainerWrapper::getInstance()->get(NewslettersRepository::class), + ContainerWrapper::getInstance()->get(NewslettersResponseBuilder::class) ); $response = $this->endpoint->get(['id' => $this->newsletter->id]); expect($response->status)->equals(APIResponse::STATUS_OK); @@ -166,7 +170,9 @@ class NewslettersTest extends \MailPoetTest { $wp, $this->makeEmpty(WCHelper::class), new SettingsController(), - $this->make(AuthorizedEmailsController::class, ['onNewsletterUpdate' => Expected::once()]) + $this->make(AuthorizedEmailsController::class, ['onNewsletterUpdate' => Expected::once()]), + ContainerWrapper::getInstance()->get(NewslettersRepository::class), + ContainerWrapper::getInstance()->get(NewslettersResponseBuilder::class) ); $response = $this->endpoint->save($valid_data); @@ -534,7 +540,9 @@ class NewslettersTest extends \MailPoetTest { $wp, $this->makeEmpty(WCHelper::class), new SettingsController(), - $this->make(AuthorizedEmailsController::class, ['onNewsletterUpdate' => Expected::never()]) + $this->make(AuthorizedEmailsController::class, ['onNewsletterUpdate' => Expected::never()]), + ContainerWrapper::getInstance()->get(NewslettersRepository::class), + ContainerWrapper::getInstance()->get(NewslettersResponseBuilder::class) ); $response = $this->endpoint->duplicate(['id' => $this->newsletter->id]);