Completed
Push — master ( e01c3b...e3b9fc )
by Jeroen De
04:48 queued 40s
created

FunFunFactory::newAccessDeniedHTMLPresenter()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
declare( strict_types = 1 );
4
5
namespace WMDE\Fundraising\Frontend\Factories;
6
7
use Doctrine\DBAL\Connection;
8
use Doctrine\DBAL\DriverManager;
9
use Doctrine\ORM\EntityManager;
10
use GuzzleHttp\Client;
11
use GuzzleHttp\ClientInterface;
12
use GuzzleHttp\Handler\CurlHandler;
13
use GuzzleHttp\HandlerStack;
14
use Mediawiki\Api\ApiUser;
15
use Mediawiki\Api\Guzzle\MiddlewareFactory;
16
use Mediawiki\Api\MediawikiApi;
17
use Monolog\Formatter\JsonFormatter;
18
use Monolog\Formatter\LineFormatter;
19
use Monolog\Handler\BufferHandler;
20
use Monolog\Handler\StreamHandler;
21
use Monolog\Logger;
22
use NumberFormatter;
23
use Psr\Log\LoggerInterface;
24
use Swift_MailTransport;
25
use Swift_NullTransport;
26
use Symfony\Component\Translation\TranslatorInterface;
27
use TNvpServiceDispatcher;
28
use Twig_Environment;
29
use Twig_Extensions_Extension_Intl;
30
use WMDE\Fundraising\Frontend\DataAccess\ApiBasedPageRetriever;
31
use WMDE\Fundraising\Frontend\DataAccess\DoctrineCommentFinder;
32
use WMDE\Fundraising\Frontend\DataAccess\DoctrineDonationAuthorizationUpdater;
33
use WMDE\Fundraising\Frontend\DataAccess\DoctrineDonationAuthorizer;
34
use WMDE\Fundraising\Frontend\DataAccess\DoctrineDonationEventLogger;
35
use WMDE\Fundraising\Frontend\DataAccess\DoctrineDonationRepository;
36
use WMDE\Fundraising\Frontend\DataAccess\DoctrineMembershipAppAuthUpdater;
37
use WMDE\Fundraising\Frontend\DataAccess\DoctrineMembershipApplicationAuthorizer;
38
use WMDE\Fundraising\Frontend\DataAccess\DoctrineMembershipApplicationRepository;
39
use WMDE\Fundraising\Frontend\DataAccess\DoctrineMembershipApplicationTracker;
40
use WMDE\Fundraising\Frontend\DataAccess\DoctrineSubscriptionRepository;
41
use WMDE\Fundraising\Frontend\DataAccess\InternetDomainNameValidator;
42
use WMDE\Fundraising\Frontend\DataAccess\McpCreditCardService;
43
use WMDE\Fundraising\Frontend\DataAccess\UniqueTransferCodeGenerator;
44
use WMDE\Fundraising\Frontend\Domain\BankDataConverter;
45
use WMDE\Fundraising\Frontend\Domain\CommentFinder;
46
use WMDE\Fundraising\Frontend\Domain\Model\EmailAddress;
47
use WMDE\Fundraising\Frontend\Domain\Model\PaymentType;
48
use WMDE\Fundraising\Frontend\Domain\ReferrerGeneralizer;
49
use WMDE\Fundraising\Frontend\Domain\Repositories\DonationRepository;
50
use WMDE\Fundraising\Frontend\Domain\Repositories\MembershipApplicationRepository;
51
use WMDE\Fundraising\Frontend\Domain\Repositories\SubscriptionRepository;
52
use WMDE\Fundraising\Frontend\Domain\SimpleTransferCodeGenerator;
53
use WMDE\Fundraising\Frontend\Domain\TransferCodeGenerator;
54
use WMDE\Fundraising\Frontend\Infrastructure\BestEffortDonationEventLogger;
55
use WMDE\Fundraising\Frontend\Infrastructure\CreditCardService;
56
use WMDE\Fundraising\Frontend\Infrastructure\DonationAuthorizationUpdater;
57
use WMDE\Fundraising\Frontend\Infrastructure\DonationAuthorizer;
58
use WMDE\Fundraising\Frontend\Infrastructure\DonationConfirmationMailer;
59
use WMDE\Fundraising\Frontend\Infrastructure\DonationEventLogger;
60
use WMDE\Fundraising\Frontend\Infrastructure\Honorifics;
61
use WMDE\Fundraising\Frontend\Infrastructure\LoggingMailer;
62
use WMDE\Fundraising\Frontend\Infrastructure\LoggingPaymentNotificationVerifier;
63
use WMDE\Fundraising\Frontend\Infrastructure\MembershipAppAuthUpdater;
64
use WMDE\Fundraising\Frontend\Infrastructure\MembershipApplicationAuthorizer;
65
use WMDE\Fundraising\Frontend\Infrastructure\MembershipApplicationTracker;
66
use WMDE\Fundraising\Frontend\Infrastructure\Messenger;
67
use WMDE\Fundraising\Frontend\Infrastructure\PageRetriever;
68
use WMDE\Fundraising\Frontend\Infrastructure\PaymentNotificationVerifier;
69
use WMDE\Fundraising\Frontend\Infrastructure\PayPalPaymentNotificationVerifier;
70
use WMDE\Fundraising\Frontend\Infrastructure\RandomTokenGenerator;
71
use WMDE\Fundraising\Frontend\Infrastructure\Repositories\LoggingCommentFinder;
72
use WMDE\Fundraising\Frontend\Infrastructure\Repositories\LoggingDonationRepository;
73
use WMDE\Fundraising\Frontend\Infrastructure\Repositories\LoggingMembershipApplicationRepository;
74
use WMDE\Fundraising\Frontend\Infrastructure\Repositories\LoggingSubscriptionRepository;
75
use WMDE\Fundraising\Frontend\Infrastructure\TemplateBasedMailer;
76
use WMDE\Fundraising\Frontend\Infrastructure\TokenGenerator;
77
use WMDE\Fundraising\Frontend\Presentation\AmountFormatter;
78
use WMDE\Fundraising\Frontend\Presentation\Content\PageContentModifier;
79
use WMDE\Fundraising\Frontend\Presentation\Content\WikiContentProvider;
80
use WMDE\Fundraising\Frontend\Presentation\CreditCardUrlConfig;
81
use WMDE\Fundraising\Frontend\Presentation\CreditCardUrlGenerator;
82
use WMDE\Fundraising\Frontend\Presentation\DonationConfirmationPageSelector;
83
use WMDE\Fundraising\Frontend\Presentation\GreetingGenerator;
84
use WMDE\Fundraising\Frontend\Presentation\PayPalUrlConfig;
85
use WMDE\Fundraising\Frontend\Presentation\PayPalUrlGenerator;
86
use WMDE\Fundraising\Frontend\Presentation\Presenters\AddSubscriptionHtmlPresenter;
87
use WMDE\Fundraising\Frontend\Presentation\Presenters\AddSubscriptionJsonPresenter;
88
use WMDE\Fundraising\Frontend\Presentation\Presenters\CancelDonationHtmlPresenter;
89
use WMDE\Fundraising\Frontend\Presentation\Presenters\CancelMembershipApplicationHtmlPresenter;
90
use WMDE\Fundraising\Frontend\Presentation\Presenters\CommentListHtmlPresenter;
91
use WMDE\Fundraising\Frontend\Presentation\Presenters\CommentListJsonPresenter;
92
use WMDE\Fundraising\Frontend\Presentation\Presenters\CommentListRssPresenter;
93
use WMDE\Fundraising\Frontend\Presentation\Presenters\ConfirmSubscriptionHtmlPresenter;
94
use WMDE\Fundraising\Frontend\Presentation\Presenters\CreditCardNotificationPresenter;
95
use WMDE\Fundraising\Frontend\Presentation\Presenters\CreditCardPaymentHtmlPresenter;
96
use WMDE\Fundraising\Frontend\Presentation\Presenters\DisplayPagePresenter;
97
use WMDE\Fundraising\Frontend\Presentation\Presenters\DonationConfirmationHtmlPresenter;
98
use WMDE\Fundraising\Frontend\Presentation\Presenters\DonationFormViolationPresenter;
99
use WMDE\Fundraising\Frontend\Presentation\Presenters\GetInTouchHtmlPresenter;
100
use WMDE\Fundraising\Frontend\Presentation\Presenters\IbanPresenter;
101
use WMDE\Fundraising\Frontend\Presentation\Presenters\InternalErrorHtmlPresenter;
102
use WMDE\Fundraising\Frontend\Presentation\Presenters\MembershipApplicationConfirmationHtmlPresenter;
103
use WMDE\Fundraising\Frontend\Presentation\Presenters\MembershipFormViolationPresenter;
104
use WMDE\Fundraising\Frontend\Presentation\TwigTemplate;
105
use WMDE\Fundraising\Frontend\UseCases\AddComment\AddCommentUseCase;
106
use WMDE\Fundraising\Frontend\UseCases\AddDonation\AddDonationUseCase;
107
use WMDE\Fundraising\Frontend\UseCases\AddSubscription\AddSubscriptionUseCase;
108
use WMDE\Fundraising\Frontend\UseCases\ApplyForMembership\ApplyForMembershipUseCase;
109
use WMDE\Fundraising\Frontend\UseCases\ApplyForMembership\MembershipApplicationValidator;
110
use WMDE\Fundraising\Frontend\UseCases\CancelDonation\CancelDonationUseCase;
111
use WMDE\Fundraising\Frontend\UseCases\CancelMembershipApplication\CancelMembershipApplicationUseCase;
112
use WMDE\Fundraising\Frontend\UseCases\CheckIban\CheckIbanUseCase;
113
use WMDE\Fundraising\Frontend\UseCases\ConfirmSubscription\ConfirmSubscriptionUseCase;
114
use WMDE\Fundraising\Frontend\UseCases\CreditCardPaymentNotification\CreditCardNotificationResponse;
115
use WMDE\Fundraising\Frontend\UseCases\CreditCardPaymentNotification\CreditCardNotificationUseCase;
116
use WMDE\Fundraising\Frontend\UseCases\DisplayPage\DisplayPageUseCase;
117
use WMDE\Fundraising\Frontend\UseCases\GenerateIban\GenerateIbanUseCase;
118
use WMDE\Fundraising\Frontend\UseCases\GetInTouch\GetInTouchUseCase;
119
use WMDE\Fundraising\Frontend\UseCases\HandlePayPalPaymentNotification\HandlePayPalPaymentNotificationUseCase;
120
use WMDE\Fundraising\Frontend\UseCases\ListComments\ListCommentsUseCase;
121
use WMDE\Fundraising\Frontend\UseCases\ShowDonationConfirmation\ShowDonationConfirmationUseCase;
122
use WMDE\Fundraising\Frontend\Validation\AllowedValuesValidator;
123
use WMDE\Fundraising\Frontend\Validation\AmountPolicyValidator;
124
use WMDE\Fundraising\Frontend\Validation\AmountValidator;
125
use WMDE\Fundraising\Frontend\Validation\BankDataValidator;
126
use WMDE\Fundraising\Frontend\Validation\DonationValidator;
127
use WMDE\Fundraising\Frontend\Validation\EmailValidator;
128
use WMDE\Fundraising\Frontend\Validation\GetInTouchValidator;
129
use WMDE\Fundraising\Frontend\Validation\IbanValidator;
130
use WMDE\Fundraising\Frontend\Validation\MembershipFeeValidator;
131
use WMDE\Fundraising\Frontend\Validation\PersonalInfoValidator;
132
use WMDE\Fundraising\Frontend\Validation\PersonNameValidator;
133
use WMDE\Fundraising\Frontend\Validation\PhysicalAddressValidator;
134
use WMDE\Fundraising\Frontend\Validation\SubscriptionDuplicateValidator;
135
use WMDE\Fundraising\Frontend\Validation\SubscriptionValidator;
136
use WMDE\Fundraising\Frontend\Validation\TemplateNameValidator;
137
use WMDE\Fundraising\Frontend\Validation\TextPolicyValidator;
138
use WMDE\Fundraising\Store\Factory as StoreFactory;
139
use WMDE\Fundraising\Store\Installer;
140
141
/**
142
 * @licence GNU GPL v2+
143
 */
144
class FunFunFactory {
145
146
	private $config;
147
148
	/**
149
	 * @var \Pimple
150
	 */
151
	private $pimple;
152
153
	public function __construct( array $config ) {
154
		$this->config = $config;
155
		$this->pimple = $this->newPimple();
156
	}
157
158
	private function newPimple(): \Pimple {
159
		$pimple = new \Pimple();
160
161
		$pimple['dbal_connection'] = $pimple->share( function() {
162
			return DriverManager::getConnection( $this->config['db'] );
163
		} );
164
165
		$pimple['entity_manager'] = $pimple->share( function() {
166
			return ( new StoreFactory( $this->getConnection() ) )->getEntityManager();
167
		} );
168
169
		$pimple['subscription_repository'] = $pimple->share( function() {
170
			return new LoggingSubscriptionRepository(
171
				new DoctrineSubscriptionRepository( $this->getEntityManager() ),
172
				$this->getLogger()
173
			);
174
		} );
175
176
		$pimple['donation_repository'] = $pimple->share( function() {
177
			return new LoggingDonationRepository(
178
				new DoctrineDonationRepository( $this->getEntityManager() ),
179
				$this->getLogger()
180
			);
181
		} );
182
183
		$pimple['membership_application_repository'] = $pimple->share( function() {
184
			return new LoggingMembershipApplicationRepository(
185
				new DoctrineMembershipApplicationRepository( $this->getEntityManager() ),
186
				$this->getLogger()
187
			);
188
		} );
189
190
		$pimple['comment_repository'] = $pimple->share( function() {
191
			return new LoggingCommentFinder(
192
				new DoctrineCommentFinder( $this->getEntityManager() ),
193
				$this->getLogger()
194
			);
195
		} );
196
197
		$pimple['mail_validator'] = $pimple->share( function() {
198
			return new EmailValidator( new InternetDomainNameValidator() );
199
		} );
200
201
		$pimple['subscription_validator'] = $pimple->share( function() {
202
			return new SubscriptionValidator(
203
				$this->getEmailValidator(),
204
				$this->getTextPolicyValidator( 'fields' ),
205
				$this->newSubscriptionDuplicateValidator(),
206
				$this->newHonorificValidator()
207
			);
208
		} );
209
210
		$pimple['template_name_validator'] = $pimple->share( function() {
211
			return new TemplateNameValidator( $this->getTwig() );
212
		} );
213
214
		$pimple['contact_validator'] = $pimple->share( function() {
215
			return new GetInTouchValidator( $this->getEmailValidator() );
216
		} );
217
218
		$pimple['greeting_generator'] = $pimple->share( function() {
219
			return new GreetingGenerator();
220
		} );
221
222
		$pimple['mw_api'] = $pimple->share( function() {
223
			return new MediawikiApi(
224
				$this->config['cms-wiki-api-url'],
225
				$this->getGuzzleClient()
226
			);
227
		} );
228
229
		$pimple['guzzle_client'] = $pimple->share( function() {
230
			$middlewareFactory = new MiddlewareFactory();
231
			$middlewareFactory->setLogger( $this->getLogger() );
232
233
			$handlerStack = HandlerStack::create( new CurlHandler() );
234
			$handlerStack->push( $middlewareFactory->retry() );
235
236
			return new Client( [
237
				'cookies' => true,
238
				'handler' => $handlerStack,
239
				'headers' => [ 'User-Agent' => 'WMDE Fundraising Frontend' ],
240
			] );
241
		} );
242
243
		$pimple['translator'] = $pimple->share( function() {
244
			$translationFactory = new TranslationFactory();
245
			$loaders = [
246
				'json' => $translationFactory->newJsonLoader()
247
			];
248
			$locale = $this->config['locale'];
249
			$translator = $translationFactory->create( $loaders, $locale );
250
			$translator->addResource( 'json', __DIR__ . '/../../app/translations/messages.' . $locale . '.json', $locale );
251
			$translator->addResource(
252
				'json',
253
				__DIR__ . '/../../app/translations/paymentTypes.' . $locale . '.json',
254
				$locale,
255
				'paymentTypes'
256
			);
257
			$translator->addResource(
258
				'json',
259
				__DIR__ . '/../../app/translations/paymentIntervals.' . $locale . '.json',
260
				$locale,
261
				'paymentIntervals'
262
			);
263
			$translator->addResource( 'json', __DIR__ . '/../../app/translations/validations.' . $locale . '.json', $locale,
264
				'validations' );
265
			return $translator;
266
		} );
267
268
		// In the future, this could be locale-specific or filled from a DB table
269
		$pimple['honorifics'] = $pimple->share( function() {
270
			return new Honorifics( [
271
				'' => 'Kein Titel',
272
				'Dr.' => 'Dr.',
273
				'Prof.' => 'Prof.',
274
				'Prof. Dr.' => 'Prof. Dr.'
275
			] );
276
		} );
277
278
		$pimple['twig_factory'] = $pimple->share( function () {
279
			return new TwigFactory( $this->config['twig'] );
280
		} );
281
282
		$pimple['twig'] = $pimple->share( function() {
283
			$twigFactory = $this->getTwigFactory();
284
			$loaders = array_filter( [
285
				$twigFactory->newFileSystemLoader(),
286
				$twigFactory->newArrayLoader(), // This is just a fallback for testing
287
				$twigFactory->newWikiPageLoader( $this->newWikiContentProvider() ),
288
			] );
289
			$extensions = [
290
				$twigFactory->newTranslationExtension( $this->getTranslator() ),
291
				new Twig_Extensions_Extension_Intl()
292
			];
293
			return $twigFactory->create( $loaders, $extensions );
294
		} );
295
296
		$pimple['logger'] = $pimple->share( function() {
297
			$logger = new Logger( 'WMDE Fundraising Frontend logger' );
298
299
			$streamHandler = new StreamHandler( $this->newLoggerPath( ( new \DateTime() )->format( 'Y-m-d\TH:i:s\Z' ) ) );
300
			$bufferHandler = new BufferHandler( $streamHandler, 500, Logger::DEBUG, true, true );
301
			$streamHandler->setFormatter( new LineFormatter( "%message%\n" ) );
302
			$logger->pushHandler( $bufferHandler );
303
304
			$errorHandler = new StreamHandler( $this->newLoggerPath( 'error' ), Logger::ERROR );
305
			$errorHandler->setFormatter( new JsonFormatter() );
306
			$logger->pushHandler( $errorHandler );
307
308
			return $logger;
309
		} );
310
311
		$pimple['messenger'] = $pimple->share( function() {
312
			return new Messenger(
313
				new Swift_MailTransport(),
314
				$this->getOperatorAddress(),
315
				$this->config['operator-displayname']
316
			);
317
		} );
318
319
		$pimple['confirmation-page-selector'] = $pimple->share( function() {
320
			return new DonationConfirmationPageSelector( $this->config['confirmation-pages'] );
321
		} );
322
323
		$pimple['paypal-payment-notification-verifier'] = $pimple->share( function() {
324
			return new LoggingPaymentNotificationVerifier(
325
				new PayPalPaymentNotificationVerifier(
326
					new Client(),
327
					$this->config['paypal']
328
				),
329
				$this->getLogger()
330
			);
331
		} );
332
333
		$pimple['credit-card-api-service'] = $pimple->share( function() {
334
			return new McpCreditCardService(
335
				new TNvpServiceDispatcher(
336
					'IMcpCreditcardService_v1_5',
337
					'https://sipg.micropayment.de/public/creditcard/v1.5/nvp/'
338
				),
339
				$this->config['creditcard']['access-key'],
340
				$this->config['creditcard']['testmode']
341
			);
342
		} );
343
344
		return $pimple;
345
	}
346
347
	public function getConnection(): Connection {
348
		return $this->pimple['dbal_connection'];
349
	}
350
351
	public function getEntityManager(): EntityManager {
352
		return $this->pimple['entity_manager'];
353
	}
354
355
	private function newDonationEventLogger(): DonationEventLogger {
356
		return new BestEffortDonationEventLogger(
357
			new DoctrineDonationEventLogger( $this->getEntityManager() ),
358
			$this->getLogger()
359
		);
360
	}
361
362
	public function newInstaller(): Installer {
363
		return ( new StoreFactory( $this->getConnection() ) )->newInstaller();
364
	}
365
366
	public function newListCommentsUseCase(): ListCommentsUseCase {
367
		return new ListCommentsUseCase( $this->getCommentFinder() );
368
	}
369
370
	public function newCommentListJsonPresenter(): CommentListJsonPresenter {
371
		return new CommentListJsonPresenter();
372
	}
373
374
	public function newCommentListRssPresenter(): CommentListRssPresenter {
375
		return new CommentListRssPresenter( new TwigTemplate(
376
			$this->getTwig(),
377
			'CommentList.rss.twig'
378
		) );
379
	}
380
381
	public function newCommentListHtmlPresenter(): CommentListHtmlPresenter {
382
		return new CommentListHtmlPresenter( $this->getLayoutTemplate( 'CommentList.html.twig' ) );
383
	}
384
385
	private function getCommentFinder(): CommentFinder {
386
		return $this->pimple['comment_repository'];
387
	}
388
389
	public function getSubscriptionRepository(): SubscriptionRepository {
390
		return $this->pimple['subscription_repository'];
391
	}
392
393
	public function setSubscriptionRepository( SubscriptionRepository $subscriptionRepository ) {
394
		$this->pimple['subscription_repository'] = $subscriptionRepository;
395
	}
396
397
	private function getSubscriptionValidator(): SubscriptionValidator {
398
		return $this->pimple['subscription_validator'];
399
	}
400
401
	public function getEmailValidator(): EmailValidator {
402
		return $this->pimple['mail_validator'];
403
	}
404
405
	private function getTemplateNameValidator(): TemplateNameValidator {
406
		return $this->pimple['template_name_validator'];
407
	}
408
409
	public function newDisplayPageUseCase(): DisplayPageUseCase {
410
		return new DisplayPageUseCase(
411
			$this->getTemplateNameValidator()
412
		);
413
	}
414
415
	public function newDisplayPagePresenter(): DisplayPagePresenter {
416
		return new DisplayPagePresenter( $this->getLayoutTemplate( 'DisplayPageLayout.twig' ) );
417
	}
418
419
	public function newAddSubscriptionHTMLPresenter(): AddSubscriptionHtmlPresenter {
420
		return new AddSubscriptionHtmlPresenter( $this->getLayoutTemplate( 'AddSubscription.twig' ), $this->getTranslator() );
421
	}
422
423
	public function newConfirmSubscriptionHtmlPresenter(): ConfirmSubscriptionHtmlPresenter {
424
		return new ConfirmSubscriptionHtmlPresenter(
425
			$this->getLayoutTemplate( 'ConfirmSubscription.html.twig' ),
426
			$this->getTranslator()
427
		);
428
	}
429
430
	public function newAddSubscriptionJSONPresenter(): AddSubscriptionJsonPresenter {
431
		return new AddSubscriptionJsonPresenter( $this->getTranslator() );
432
	}
433
434
	public function newGetInTouchHTMLPresenter(): GetInTouchHtmlPresenter {
435
		return new GetInTouchHtmlPresenter( $this->getLayoutTemplate( 'GetInTouch.twig' ), $this->getTranslator() );
436
	}
437
438
	public function getTwig(): Twig_Environment {
439
		return $this->pimple['twig'];
440
	}
441
442
	/**
443
	 * Get a template, with the content for the layout areas filled in.
444
	 *
445
	 * @param string $templateName
446
	 * @return TwigTemplate
447
	 */
448
	private function getLayoutTemplate( string $templateName ): TwigTemplate {
449
		 return new TwigTemplate(
450
			$this->getTwig(),
451
			$templateName,
452
			$this->getDefaultTwigVariables()
453
		);
454
	}
455
456
	/**
457
	 * Get a layouted template that includes another template
458
	 *
459
	 * @param string $templateName Template to include
460
	 * @return TwigTemplate
461
	 */
462
	private function getIncludeTemplate( string $templateName ): TwigTemplate {
463
		return new TwigTemplate(
464
			$this->getTwig(),
465
			'IncludeInLayout.twig',
466
			array_merge(
467
				$this->getDefaultTwigVariables(),
468
				[ 'main_template' => $templateName]
469
			)
470
		);
471
	}
472
473
	private function getDefaultTwigVariables() {
474
		return [
475
			'basepath' => $this->config['web-basepath'],
476
			'honorifics' => $this->getHonorifics()->getList(),
477
			'header_template' => $this->config['default-layout-templates']['header'],
478
			'footer_template' => $this->config['default-layout-templates']['footer'],
479
			'no_js_notice_template' => $this->config['default-layout-templates']['no-js-notice'],
480
		];
481
	}
482
483
	private function newReferrerGeneralizer() {
484
		return new ReferrerGeneralizer(
485
			$this->config['referrer-generalization']['default'],
486
			$this->config['referrer-generalization']['domain-map']
487
		);
488
	}
489
490
	private function newPageRetriever(): PageRetriever {
491
		return new ApiBasedPageRetriever(
492
			$this->getMediaWikiApi(),
493
			new ApiUser( $this->config['cms-wiki-user'], $this->config['cms-wiki-password'] ),
494
			$this->getLogger()
495
		);
496
	}
497
498
	private function getMediaWikiApi(): MediawikiApi {
499
		return $this->pimple['mw_api'];
500
	}
501
502
	public function setMediaWikiApi( MediawikiApi $api ) {
503
		$this->pimple['mw_api'] = $api;
504
	}
505
506
	private function getGuzzleClient(): ClientInterface {
507
		return $this->pimple['guzzle_client'];
508
	}
509
510
	private function newWikiContentProvider() {
511
		return new WikiContentProvider(
512
			$this->newPageRetriever(),
513
			$this->newPageContentModifier(),
514
			$this->config['cms-wiki-title-prefix']
515
		);
516
	}
517
518
	public function getLogger(): LoggerInterface {
519
		return $this->pimple['logger'];
520
	}
521
522
	private function newLoggerPath( string $fileName ): string {
523
		return __DIR__ . '/../../var/log/' . $fileName . '.log';
524
	}
525
526
	private function newPageContentModifier(): PageContentModifier {
527
		return new PageContentModifier(
528
			$this->getLogger()
529
		);
530
	}
531
532
	public function newAddSubscriptionUseCase(): AddSubscriptionUseCase {
533
		return new AddSubscriptionUseCase(
534
			$this->getSubscriptionRepository(),
535
			$this->getSubscriptionValidator(),
536
			$this->newAddSubscriptionMailer()
537
		);
538
	}
539
540
	public function newConfirmSubscriptionUseCase(): ConfirmSubscriptionUseCase {
541
		return new ConfirmSubscriptionUseCase(
542
			$this->getSubscriptionRepository(),
543
			$this->newConfirmSubscriptionMailer()
544
		);
545
	}
546
547
	private function newAddSubscriptionMailer(): TemplateBasedMailer {
548
		return $this->newTemplateMailer(
549
			new TwigTemplate(
550
				$this->getTwig(),
551
				'Mail_Subscription_Request.twig',
552
				[
553
					'basepath' => $this->config['web-basepath'],
554
					'greeting_generator' => $this->getGreetingGenerator()
555
				]
556
			),
557
			'mail_subject_membership'
558
		);
559
	}
560
561
	private function newConfirmSubscriptionMailer(): TemplateBasedMailer {
562
		return $this->newTemplateMailer(
563
			new TwigTemplate(
564
					$this->getTwig(),
565
					'Mail_Subscription_Confirmation.twig',
566
					[ 'greeting_generator' => $this->getGreetingGenerator() ]
567
			),
568
			'mail_subject_membership'
569
		);
570
	}
571
572
	private function newTemplateMailer( TwigTemplate $template, string $messageKey ): TemplateBasedMailer {
573
		$mailer = new TemplateBasedMailer(
574
			$this->getMessenger(),
575
			$template,
576
			$this->getTranslator()->trans( $messageKey )
577
		);
578
579
		return new LoggingMailer( $mailer, $this->getLogger() );
580
	}
581
582
	public function getGreetingGenerator() {
583
		return $this->pimple['greeting_generator'];
584
	}
585
586
	public function newCheckIbanUseCase(): CheckIbanUseCase {
587
		return new CheckIbanUseCase( $this->newBankDataConverter() );
588
	}
589
590
	public function newGenerateIbanUseCase(): GenerateIbanUseCase {
591
		return new GenerateIbanUseCase( $this->newBankDataConverter() );
592
	}
593
594
	public function newIbanPresenter(): IbanPresenter {
595
		return new IbanPresenter();
596
	}
597
598
	public function newBankDataConverter() {
599
		return new BankDataConverter( $this->config['bank-data-file'] );
600
	}
601
602
	public function setSubscriptionValidator( SubscriptionValidator $subscriptionValidator ) {
603
		$this->pimple['subscription_validator'] = $subscriptionValidator;
604
	}
605
606
	public function setPageTitlePrefix( string $prefix ) {
607
		$this->config['cms-wiki-title-prefix'] = $prefix;
608
	}
609
610
	public function newGetInTouchUseCase() {
611
		return new GetInTouchUseCase(
612
			$this->getContactValidator(),
613
			$this->getMessenger(),
614
			$this->newContactConfirmationMailer()
615
		);
616
	}
617
618
	private function newContactConfirmationMailer(): TemplateBasedMailer {
619
		return $this->newTemplateMailer(
620
			new TwigTemplate( $this->getTwig(), 'GetInTouchConfirmation.twig' ),
621
			'mail_subject_getintouch'
622
		);
623
	}
624
625
	private function getContactValidator(): GetInTouchValidator {
626
		return $this->pimple['contact_validator'];
627
	}
628
629
	private function newSubscriptionDuplicateValidator(): SubscriptionDuplicateValidator {
630
		return new SubscriptionDuplicateValidator(
631
				$this->getSubscriptionRepository(),
632
				$this->newSubscriptionDuplicateCutoffDate()
633
		);
634
	}
635
636
	private function newSubscriptionDuplicateCutoffDate(): \DateTime {
637
		$cutoffDateTime = new \DateTime();
638
		$cutoffDateTime->sub( new \DateInterval( $this->config['subscription-interval'] ) );
639
		return $cutoffDateTime;
640
	}
641
642
	private function newHonorificValidator(): AllowedValuesValidator {
643
		return new AllowedValuesValidator( $this->getHonorifics()->getKeys() );
644
	}
645
646
	private function getHonorifics(): Honorifics {
647
		return $this->pimple['honorifics'];
648
	}
649
650
	private function newPaymentTypeValidator(): AllowedValuesValidator {
651
		return new AllowedValuesValidator( PaymentType::getPaymentTypes() );
652
	}
653
654
	private function newBankDataValidator(): BankDataValidator {
655
		return new BankDataValidator( new IbanValidator( $this->newBankDataConverter() ) );
656
	}
657
658
	private function getMessenger(): Messenger {
659
		return $this->pimple['messenger'];
660
	}
661
662
	public function setMessenger( Messenger $messenger ) {
663
		$this->pimple['messenger'] = $messenger;
664
	}
665
666
	public function setNullMessenger() {
667
		$this->setMessenger( new Messenger(
668
			Swift_NullTransport::newInstance(),
669
			$this->getOperatorAddress()
670
		) );
671
	}
672
673
	public function getOperatorAddress() {
674
		return new EmailAddress( $this->config['operator-email'] );
675
	}
676
677
	public function newInternalErrorHTMLPresenter(): InternalErrorHtmlPresenter {
678
		return new InternalErrorHtmlPresenter( $this->getLayoutTemplate( 'Error.twig' ) );
679
	}
680
681
	public function newAccessDeniedHTMLPresenter(): InternalErrorHtmlPresenter {
682
		return new InternalErrorHtmlPresenter( $this->getLayoutTemplate( 'AccessDenied.twig' ) );
683
	}
684
685
	public function getTranslator(): TranslatorInterface {
686
		return $this->pimple['translator'];
687
	}
688
689
	public function setTranslator( TranslatorInterface $translator ) {
690
		$this->pimple['translator'] = $translator;
691
	}
692
693
	private function getTwigFactory(): TwigFactory {
694
		return $this->pimple['twig_factory'];
695
	}
696
697
	private function getTextPolicyValidator( $policyName ) {
698
		$policyValidator = new TextPolicyValidator();
699
700
		$contentProvider = $this->newWikiContentProvider();
701
		$textPolicyConfig = $this->config['text-policies'][$policyName];
702
703
		// TODO: this is not the place to retrieve resources over the network
704
		$policyValidator->addBadWordsFromArray( $this->loadWordsFromWiki(
705
			$contentProvider,
706
			$textPolicyConfig['badwords'] ?? ''
707
		) );
708
		$policyValidator->addWhiteWordsFromArray( $this->loadWordsFromWiki(
709
			$contentProvider,
710
			$textPolicyConfig['whitewords'] ?? ''
711
		) );
712
713
		return $policyValidator;
714
	}
715
716
	private function loadWordsFromWiki( WikiContentProvider $contentProvider, string $pageName ): array {
717
		if ( $pageName === '' ) {
718
			return [ ];
719
		}
720
		$content = $contentProvider->getContent( $pageName, 'raw' );
721
		$words = array_map( 'trim', explode( "\n", $content ) );
722
723
		return array_filter( $words );
724
	}
725
726
	public function newCancelDonationUseCase( string $updateToken ): CancelDonationUseCase {
727
		return new CancelDonationUseCase(
728
			$this->getDonationRepository(),
729
			$this->newCancelDonationMailer(),
730
			$this->newDonationAuthorizer( $updateToken )
731
		);
732
	}
733
734
	private function newCancelDonationMailer(): TemplateBasedMailer {
735
		return $this->newTemplateMailer(
736
			new TwigTemplate(
737
				$this->getTwig(),
738
				'Mail_Donation_Cancellation_Confirmation.twig',
739
				[ 'greeting_generator' => $this->getGreetingGenerator() ]
740
			),
741
			'mail_subject_confirm_cancellation'
742
		);
743
	}
744
745
	public function newAddDonationUseCase(): AddDonationUseCase {
746
		return new AddDonationUseCase(
747
			$this->getDonationRepository(),
748
			$this->newDonationValidator(),
749
			$this->newReferrerGeneralizer(),
750
			$this->newDonationConfirmationMailer(),
751
			$this->newBankTransferCodeGenerator(),
752
			$this->newBankDataConverter(),
753
			$this->newTokenGenerator(),
754
			$this->newDonationAuthorizationUpdater()
755
		);
756
	}
757
758
	private function newBankTransferCodeGenerator(): TransferCodeGenerator {
759
		return new UniqueTransferCodeGenerator(
760
			new SimpleTransferCodeGenerator(),
761
			$this->getEntityManager()
762
		);
763
	}
764
765
	private function newDonationValidator(): DonationValidator {
766
		return new DonationValidator(
767
			$this->newAmountValidator(),
768
			new AmountPolicyValidator( 1000, 200, 300 ),
769
			$this->newPersonalInfoValidator(),
770
			$this->getTextPolicyValidator( 'fields' ),
771
			$this->newPaymentTypeValidator(),
772
			$this->newBankDataValidator()
773
		);
774
	}
775
776
	public function newPersonalInfoValidator(): PersonalInfoValidator {
777
		return new PersonalInfoValidator(
778
			new PersonNameValidator(),
779
			new PhysicalAddressValidator(),
780
			$this->getEmailValidator()
781
		);
782
	}
783
784
	private function newDonationConfirmationMailer(): DonationConfirmationMailer {
785
		return new DonationConfirmationMailer(
786
			$this->newTemplateMailer(
787
				new TwigTemplate(
788
					$this->getTwig(),
789
					'Mail_Donation_Confirmation.twig', // TODO: ongoing unification of different templates
790
					[
791
						'basepath' => $this->config['web-basepath']
792
					]
793
				),
794
				'mail_subject_confirm_donation'
795
			)
796
		);
797
	}
798
799
	public function newPayPalUrlGenerator() {
800
		return new PayPalUrlGenerator( $this->getPayPalUrlConfig() );
801
	}
802
803
	private function getPayPalUrlConfig() {
804
		return PayPalUrlConfig::newFromConfig( $this->config['paypal'] );
805
	}
806
807
	private function newCreditCardUrlGenerator() {
808
		return new CreditCardUrlGenerator( $this->newCreditCardUrlConfig() );
809
	}
810
811
	private function newCreditCardUrlConfig() {
812
		return CreditCardUrlConfig::newFromConfig( $this->config['creditcard'] );
813
	}
814
815
	public function getDonationRepository(): DonationRepository {
816
		return $this->pimple['donation_repository'];
817
	}
818
819
	public function newAmountValidator(): AmountValidator {
820
		return new AmountValidator(
821
			0.01,
822
			[
823
				PaymentType::CREDIT_CARD => 1,
824
				PaymentType::PAYPAL => 1,
825
			]
826
		);
827
	}
828
829
	private function newAmountFormatter(): AmountFormatter {
830
		return new AmountFormatter( $this->config['locale'] );
831
	}
832
833
	public function newDecimalNumberFormatter(): NumberFormatter {
834
		return new NumberFormatter( $this->config['locale'], NumberFormatter::DECIMAL );
835
	}
836
837
	public function newAddCommentUseCase( string $updateToken ): AddCommentUseCase {
838
		return new AddCommentUseCase(
839
			$this->getDonationRepository(),
840
			$this->newDonationAuthorizer( $updateToken ),
841
			$this->getTextPolicyValidator( 'comment' )
842
		);
843
	}
844
845
	private function newDonationAuthorizer( string $updateToken = null, string $accessToken = null ): DonationAuthorizer {
846
		return new DoctrineDonationAuthorizer(
847
			$this->getEntityManager(),
848
			$updateToken,
849
			$accessToken
850
		);
851
	}
852
853
	public function newDonationAuthorizationUpdater(): DonationAuthorizationUpdater {
854
		return new DoctrineDonationAuthorizationUpdater( $this->getEntityManager() );
855
	}
856
857
	public function newTokenGenerator(): TokenGenerator {
858
		return new RandomTokenGenerator(
859
			$this->config['token-length'],
860
			new \DateInterval( $this->config['token-validity-timestamp'] )
861
		);
862
	}
863
864
	public function newDonationConfirmationPresenter() {
865
		return new DonationConfirmationHtmlPresenter(
866
			$this->getLayoutTemplate( 'DonationConfirmation.twig' )
867
		);
868
	}
869
870
	public function newCreditCardPaymentHtmlPresenter() {
871
		return new CreditCardPaymentHtmlPresenter(
872
			$this->getIncludeTemplate( 'CreditCardPayment.html.twig' ),
873
			$this->getTranslator(),
874
			$this->newCreditCardUrlGenerator()
875
		);
876
	}
877
878
	public function newCancelDonationHtmlPresenter() {
879
		return new CancelDonationHtmlPresenter(
880
			$this->getIncludeTemplate( 'Donation_Cancellation_Confirmation.twig' )
881
		);
882
	}
883
884
	public function newApplyForMembershipUseCase(): ApplyForMembershipUseCase {
885
		return new ApplyForMembershipUseCase(
886
			$this->getMembershipApplicationRepository(),
887
			$this->newMembershipAuthUpdater(),
888
			$this->newApplyForMembershipMailer(),
889
			$this->newTokenGenerator(),
890
			$this->newMembershipApplicationValidator(),
891
			$this->newMembershipApplicationTracker()
892
		);
893
	}
894
895
	private function newApplyForMembershipMailer(): TemplateBasedMailer {
896
		return $this->newTemplateMailer(
897
			new TwigTemplate(
898
				$this->getTwig(),
899
				'Mail_Membership_Application_Confirmation.twig',
900
				[ 'greeting_generator' => $this->getGreetingGenerator() ]
901
			),
902
			'mail_subject_confirm_membership_application'
903
		);
904
	}
905
906
	private function newMembershipApplicationValidator(): MembershipApplicationValidator {
907
		return new MembershipApplicationValidator(
908
			new MembershipFeeValidator(),
909
			$this->newBankDataValidator(),
910
			$this->getEmailValidator()
911
		);
912
	}
913
914
	private function newMembershipApplicationTracker(): MembershipApplicationTracker {
915
		return new DoctrineMembershipApplicationTracker( $this->getEntityManager() );
916
	}
917
918
	private function newMembershipAuthUpdater(): MembershipAppAuthUpdater {
919
		return new DoctrineMembershipAppAuthUpdater(
920
			$this->getEntityManager()
921
		);
922
	}
923
924
	public function newCancelMembershipApplicationUseCase( string $updateToken ): CancelMembershipApplicationUseCase {
925
		return new CancelMembershipApplicationUseCase(
926
			$this->newMembershipApplicationAuthorizer( $updateToken ),
927
			$this->getMembershipApplicationRepository(),
928
			$this->newCancelMembershipApplicationMailer()
929
		);
930
	}
931
932
	private function newMembershipApplicationAuthorizer(
933
		string $updateToken = null, string $accessToken = null ): MembershipApplicationAuthorizer {
934
935
		return new DoctrineMembershipApplicationAuthorizer(
936
			$this->getEntityManager(),
937
			$updateToken,
938
			$accessToken
939
		);
940
	}
941
942
	public function getMembershipApplicationRepository(): MembershipApplicationRepository {
943
		return $this->pimple['membership_application_repository'];
944
	}
945
946
	private function newCancelMembershipApplicationMailer(): TemplateBasedMailer {
947
		return $this->newTemplateMailer(
948
			new TwigTemplate(
949
				$this->getTwig(),
950
				'Mail_Membership_Application_Cancellation_Confirmation.twig',
951
				[ 'greeting_generator' => $this->getGreetingGenerator() ]
952
			),
953
			'mail_subject_confirm_membership_application_cancellation'
954
		);
955
	}
956
957
	public function newShowDonationConfirmationUseCase( string $accessToken ): ShowDonationConfirmationUseCase {
958
		return new ShowDonationConfirmationUseCase(
959
			$this->newDonationAuthorizer( null, $accessToken ),
960
			$this->getDonationRepository()
961
		);
962
	}
963
964
	public function setDonationConfirmationPageSelector( DonationConfirmationPageSelector $selector ) {
965
		$this->pimple['confirmation-page-selector'] = $selector;
966
	}
967
968
	public function getDonationConfirmationPageSelector() {
969
		return $this->pimple['confirmation-page-selector'];
970
	}
971
972
	public function newDonationFormViolationPresenter() {
973
		$template = $this->getLayoutTemplate( 'DisplayPageLayout.twig' );
974
		// TODO make this dependent on the 'form' value from the HTTP POST request
975
		// (we need different form pages for A/B testing)
976
		$template->context['main_template'] = 'DonationForm.html.twig';
0 ignored issues
show
Bug introduced by
The property context does not seem to exist in WMDE\Fundraising\Fronten...esentation\TwigTemplate.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
977
		return new DonationFormViolationPresenter( $template, $this->newAmountFormatter() );
978
	}
979
980
	public function newHandlePayPalPaymentNotificationUseCase( string $updateToken ) {
981
		return new HandlePayPalPaymentNotificationUseCase(
982
			$this->getDonationRepository(),
983
			$this->newDonationAuthorizer( $updateToken ),
984
			$this->newDonationConfirmationMailer(),
985
			$this->getLogger(),
986
			$this->newDonationEventLogger()
987
		);
988
	}
989
990
	public function getPayPalPaymentNotificationVerifier(): PaymentNotificationVerifier {
991
		return $this->pimple['paypal-payment-notification-verifier'];
992
	}
993
994
	public function setPayPalPaymentNotificationVerifier( PaymentNotificationVerifier $verifier ) {
995
		$this->pimple['paypal-payment-notification-verifier'] = $verifier;
996
	}
997
998
	public function newCreditCardNotificationUseCase( string $updateToken ) {
999
		return new CreditCardNotificationUseCase(
1000
			$this->getDonationRepository(),
1001
			$this->newDonationAuthorizer( $updateToken ),
1002
			$this->getCreditCardService(),
1003
			$this->newDonationConfirmationMailer(),
1004
			$this->getLogger(),
1005
			$this->newDonationEventLogger()
1006
		);
1007
	}
1008
1009
	public function newCancelMembershipApplicationHtmlPresenter() {
1010
		return new CancelMembershipApplicationHtmlPresenter(
1011
			$this->getIncludeTemplate( 'Membership_Application_Cancellation_Confirmation.twig' )
1012
		);
1013
	}
1014
1015
	public function newMembershipApplicationConfirmationHtmlPresenter() {
1016
		return new MembershipApplicationConfirmationHtmlPresenter(
1017
			$this->getIncludeTemplate( 'MembershipApplicationConfirmation.html.twig' )
1018
		);
1019
	}
1020
1021
	public function newMembershipFormViolationPresenter() {
1022
		return new MembershipFormViolationPresenter(
1023
			$this->getIncludeTemplate( 'MembershipApplication.html.twig' )
1024
		);
1025
	}
1026
1027
	public function setCreditCardService( CreditCardService $ccService ) {
1028
		$this->pimple['credit-card-api-service'] = $ccService;
1029
	}
1030
1031
	public function getCreditCardService(): CreditCardService {
1032
		return $this->pimple['credit-card-api-service'];
1033
	}
1034
1035
	public function newCreditCardNotificationPresenter(): CreditCardNotificationPresenter {
1036
		return new CreditCardNotificationPresenter(
1037
			new TwigTemplate(
1038
				$this->getTwig(),
1039
				'CreditCardPaymentNotification.twig',
1040
				[ 'returnUrl' => $this->config['creditcard']['return-url'] ]
1041
			)
1042
		);
1043
	}
1044
1045
}
1046