Completed
Pull Request — master (#575)
by Jeroen De
03:49
created

anonymous//src/Factories/FunFunFactory.php$0   A

Complexity

Total Complexity 2

Size/Duplication

Total Lines 23
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 1

Importance

Changes 0
Metric Value
wmc 2
lcom 0
cbo 1
dl 0
loc 23
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare( strict_types = 1 );
4
5
namespace WMDE\Fundraising\Frontend\Factories;
6
7
use Doctrine\Common\Cache\Cache;
8
use Doctrine\Common\Cache\FilesystemCache;
9
use Doctrine\Common\Cache\VoidCache;
10
use Doctrine\DBAL\Connection;
11
use Doctrine\DBAL\DriverManager;
12
use Doctrine\ORM\EntityManager;
13
use GuzzleHttp\Client;
14
use GuzzleHttp\ClientInterface;
15
use GuzzleHttp\Handler\CurlHandler;
16
use GuzzleHttp\HandlerStack;
17
use Mediawiki\Api\ApiUser;
18
use Mediawiki\Api\Guzzle\MiddlewareFactory;
19
use Mediawiki\Api\MediawikiApi;
20
use Monolog\Formatter\JsonFormatter;
21
use Monolog\Formatter\LineFormatter;
22
use Monolog\Handler\BufferHandler;
23
use Monolog\Handler\StreamHandler;
24
use Monolog\Logger;
25
use NumberFormatter;
26
use Psr\Log\LoggerInterface;
27
use Swift_MailTransport;
28
use Swift_NullTransport;
29
use Symfony\Component\Translation\TranslatorInterface;
30
use TNvpServiceDispatcher;
31
use Twig_Environment;
32
use Twig_Extensions_Extension_Intl;
33
use WMDE\Fundraising\Frontend\DataAccess\ApiBasedPageRetriever;
34
use WMDE\Fundraising\Frontend\DataAccess\DoctrineCommentFinder;
35
use WMDE\Fundraising\Frontend\DataAccess\DoctrineDonationAuthorizer;
36
use WMDE\Fundraising\Frontend\DataAccess\DoctrineDonationEventLogger;
37
use WMDE\Fundraising\Frontend\DataAccess\DoctrineDonationPrePersistSubscriber;
38
use WMDE\Fundraising\Frontend\DataAccess\DoctrineDonationRepository;
39
use WMDE\Fundraising\Frontend\DataAccess\DoctrineDonationTokenFetcher;
40
use WMDE\Fundraising\Frontend\DataAccess\DoctrineMembershipApplicationAuthorizer;
41
use WMDE\Fundraising\Frontend\DataAccess\DoctrineMembershipApplicationPiwikTracker;
42
use WMDE\Fundraising\Frontend\DataAccess\DoctrineMembershipApplicationPrePersistSubscriber;
43
use WMDE\Fundraising\Frontend\DataAccess\DoctrineMembershipApplicationRepository;
44
use WMDE\Fundraising\Frontend\DataAccess\DoctrineMembershipApplicationTokenFetcher;
45
use WMDE\Fundraising\Frontend\DataAccess\DoctrineMembershipApplicationTracker;
46
use WMDE\Fundraising\Frontend\DataAccess\DoctrineSubscriptionRepository;
47
use WMDE\Fundraising\Frontend\DataAccess\InternetDomainNameValidator;
48
use WMDE\Fundraising\Frontend\DataAccess\McpCreditCardService;
49
use WMDE\Fundraising\Frontend\DataAccess\UniqueTransferCodeGenerator;
50
use WMDE\Fundraising\Frontend\Domain\BankDataConverter;
51
use WMDE\Fundraising\Frontend\Domain\CommentFinder;
52
use WMDE\Fundraising\Frontend\Domain\Model\EmailAddress;
53
use WMDE\Fundraising\Frontend\Domain\ReferrerGeneralizer;
54
use WMDE\Fundraising\Frontend\Domain\Repositories\DonationRepository;
55
use WMDE\Fundraising\Frontend\Domain\Repositories\MembershipApplicationRepository;
56
use WMDE\Fundraising\Frontend\Domain\Repositories\SubscriptionRepository;
57
use WMDE\Fundraising\Frontend\Domain\SimpleTransferCodeGenerator;
58
use WMDE\Fundraising\Frontend\Domain\TransferCodeGenerator;
59
use WMDE\Fundraising\Frontend\Infrastructure\BestEffortDonationEventLogger;
60
use WMDE\Fundraising\Frontend\Infrastructure\CachingPageRetriever;
61
use WMDE\Fundraising\Frontend\Infrastructure\CreditCardService;
62
use WMDE\Fundraising\Frontend\Infrastructure\DonationAuthorizer;
63
use WMDE\Fundraising\Frontend\Infrastructure\DonationConfirmationMailer;
64
use WMDE\Fundraising\Frontend\Infrastructure\DonationEventLogger;
65
use WMDE\Fundraising\Frontend\Infrastructure\DonationTokenFetcher;
66
use WMDE\Fundraising\Frontend\Infrastructure\Honorifics;
67
use WMDE\Fundraising\Frontend\Infrastructure\LoggingMailer;
68
use WMDE\Fundraising\Frontend\Infrastructure\LoggingPaymentNotificationVerifier;
69
use WMDE\Fundraising\Frontend\Infrastructure\MembershipApplicationAuthorizer;
70
use WMDE\Fundraising\Frontend\Infrastructure\MembershipApplicationPiwikTracker;
71
use WMDE\Fundraising\Frontend\Infrastructure\MembershipApplicationTokenFetcher;
72
use WMDE\Fundraising\Frontend\Infrastructure\MembershipApplicationTracker;
73
use WMDE\Fundraising\Frontend\Infrastructure\Messenger;
74
use WMDE\Fundraising\Frontend\Infrastructure\PageRetriever;
75
use WMDE\Fundraising\Frontend\Infrastructure\PageRetrieverBasedStringList;
76
use WMDE\Fundraising\Frontend\Infrastructure\PaymentNotificationVerifier;
77
use WMDE\Fundraising\Frontend\Infrastructure\PayPalPaymentNotificationVerifier;
78
use WMDE\Fundraising\Frontend\Infrastructure\RandomTokenGenerator;
79
use WMDE\Fundraising\Frontend\Infrastructure\Repositories\LoggingCommentFinder;
80
use WMDE\Fundraising\Frontend\Infrastructure\Repositories\LoggingDonationRepository;
81
use WMDE\Fundraising\Frontend\Infrastructure\Repositories\LoggingMembershipApplicationRepository;
82
use WMDE\Fundraising\Frontend\Infrastructure\Repositories\LoggingSubscriptionRepository;
83
use WMDE\Fundraising\Frontend\Infrastructure\TemplateBasedMailer;
84
use WMDE\Fundraising\Frontend\Infrastructure\TokenGenerator;
85
use WMDE\Fundraising\Frontend\Infrastructure\AllOfTheCachePurger;
86
use WMDE\Fundraising\Frontend\Presentation\AmountFormatter;
87
use WMDE\Fundraising\Frontend\Presentation\Content\PageContentModifier;
88
use WMDE\Fundraising\Frontend\Infrastructure\ModifyingPageRetriever;
89
use WMDE\Fundraising\Frontend\Presentation\CreditCardUrlConfig;
90
use WMDE\Fundraising\Frontend\Presentation\CreditCardUrlGenerator;
91
use WMDE\Fundraising\Frontend\Presentation\DonationConfirmationPageSelector;
92
use WMDE\Fundraising\Frontend\Presentation\GreetingGenerator;
93
use WMDE\Fundraising\Frontend\Presentation\PayPalUrlConfig;
94
use WMDE\Fundraising\Frontend\Presentation\PayPalUrlGenerator;
95
use WMDE\Fundraising\Frontend\Presentation\Presenters\AddSubscriptionHtmlPresenter;
96
use WMDE\Fundraising\Frontend\Presentation\Presenters\AddSubscriptionJsonPresenter;
97
use WMDE\Fundraising\Frontend\Presentation\Presenters\CancelDonationHtmlPresenter;
98
use WMDE\Fundraising\Frontend\Presentation\Presenters\CancelMembershipApplicationHtmlPresenter;
99
use WMDE\Fundraising\Frontend\Presentation\Presenters\CommentListHtmlPresenter;
100
use WMDE\Fundraising\Frontend\Presentation\Presenters\CommentListJsonPresenter;
101
use WMDE\Fundraising\Frontend\Presentation\Presenters\CommentListRssPresenter;
102
use WMDE\Fundraising\Frontend\Presentation\Presenters\ConfirmSubscriptionHtmlPresenter;
103
use WMDE\Fundraising\Frontend\Presentation\Presenters\CreditCardNotificationPresenter;
104
use WMDE\Fundraising\Frontend\Presentation\Presenters\CreditCardPaymentHtmlPresenter;
105
use WMDE\Fundraising\Frontend\Presentation\Presenters\DisplayPagePresenter;
106
use WMDE\Fundraising\Frontend\Presentation\Presenters\DonationConfirmationHtmlPresenter;
107
use WMDE\Fundraising\Frontend\Presentation\Presenters\DonationFormViolationPresenter;
108
use WMDE\Fundraising\Frontend\Presentation\Presenters\GetInTouchHtmlPresenter;
109
use WMDE\Fundraising\Frontend\Presentation\Presenters\IbanPresenter;
110
use WMDE\Fundraising\Frontend\Presentation\Presenters\InternalErrorHtmlPresenter;
111
use WMDE\Fundraising\Frontend\Presentation\Presenters\MembershipApplicationConfirmationHtmlPresenter;
112
use WMDE\Fundraising\Frontend\Presentation\Presenters\MembershipFormViolationPresenter;
113
use WMDE\Fundraising\Frontend\Presentation\TwigTemplate;
114
use WMDE\Fundraising\Frontend\UseCases\AddComment\AddCommentUseCase;
115
use WMDE\Fundraising\Frontend\UseCases\AddComment\AddCommentValidator;
116
use WMDE\Fundraising\Frontend\UseCases\AddDonation\AddDonationPolicyValidator;
117
use WMDE\Fundraising\Frontend\UseCases\AddDonation\AddDonationUseCase;
118
use WMDE\Fundraising\Frontend\UseCases\AddDonation\AddDonationValidator;
119
use WMDE\Fundraising\Frontend\UseCases\AddSubscription\AddSubscriptionUseCase;
120
use WMDE\Fundraising\Frontend\UseCases\ApplyForMembership\ApplyForMembershipUseCase;
121
use WMDE\Fundraising\Frontend\UseCases\ApplyForMembership\MembershipApplicationValidator;
122
use WMDE\Fundraising\Frontend\UseCases\CancelDonation\CancelDonationUseCase;
123
use WMDE\Fundraising\Frontend\UseCases\CancelMembershipApplication\CancelMembershipApplicationUseCase;
124
use WMDE\Fundraising\Frontend\UseCases\CheckIban\CheckIbanUseCase;
125
use WMDE\Fundraising\Frontend\UseCases\ConfirmSubscription\ConfirmSubscriptionUseCase;
126
use WMDE\Fundraising\Frontend\UseCases\CreditCardPaymentNotification\CreditCardNotificationUseCase;
127
use WMDE\Fundraising\Frontend\UseCases\DisplayPage\DisplayPageUseCase;
128
use WMDE\Fundraising\Frontend\UseCases\GenerateIban\GenerateIbanUseCase;
129
use WMDE\Fundraising\Frontend\UseCases\GetInTouch\GetInTouchUseCase;
130
use WMDE\Fundraising\Frontend\UseCases\HandlePayPalPaymentNotification\HandlePayPalPaymentNotificationUseCase;
131
use WMDE\Fundraising\Frontend\UseCases\ListComments\ListCommentsUseCase;
132
use WMDE\Fundraising\Frontend\UseCases\PurgeCache\PurgeCacheUseCase;
133
use WMDE\Fundraising\Frontend\UseCases\ShowDonationConfirmation\ShowDonationConfirmationUseCase;
134
use WMDE\Fundraising\Frontend\UseCases\ShowMembershipApplicationConfirmation\ShowMembershipApplicationConfirmationUseCase;
135
use WMDE\Fundraising\Frontend\Validation\AllowedValuesValidator;
136
use WMDE\Fundraising\Frontend\Validation\AmountPolicyValidator;
137
use WMDE\Fundraising\Frontend\Validation\AmountValidator;
138
use WMDE\Fundraising\Frontend\Validation\BankDataValidator;
139
use WMDE\Fundraising\Frontend\Validation\EmailValidator;
140
use WMDE\Fundraising\Frontend\Validation\GetInTouchValidator;
141
use WMDE\Fundraising\Frontend\Validation\IbanValidator;
142
use WMDE\Fundraising\Frontend\Validation\MembershipFeeValidator;
143
use WMDE\Fundraising\Frontend\Validation\PersonalInfoValidator;
144
use WMDE\Fundraising\Frontend\Validation\PersonNameValidator;
145
use WMDE\Fundraising\Frontend\Validation\PhysicalAddressValidator;
146
use WMDE\Fundraising\Frontend\Validation\SubscriptionDuplicateValidator;
147
use WMDE\Fundraising\Frontend\Validation\SubscriptionValidator;
148
use WMDE\Fundraising\Frontend\Validation\TemplateNameValidator;
149
use WMDE\Fundraising\Frontend\Validation\TextPolicyValidator;
150
use WMDE\Fundraising\Store\Factory as StoreFactory;
151
use WMDE\Fundraising\Store\Installer;
152
153
/**
154
 * @licence GNU GPL v2+
155
 */
156
class FunFunFactory {
157
158
	private $config;
159
160
	/**
161
	 * @var \Pimple
162
	 */
163
	private $pimple;
164
	private $addDoctrineSubscribers = true;
165
166
	public function __construct( array $config ) {
167
		$this->config = $config;
168
		$this->pimple = $this->newPimple();
169
	}
170
171
	private function newPimple(): \Pimple {
172
		$pimple = new \Pimple();
173
174
		$pimple['dbal_connection'] = $pimple->share( function() {
175
			return DriverManager::getConnection( $this->config['db'] );
176
		} );
177
178
		$pimple['entity_manager'] = $pimple->share( function() {
179
			$entityManager = ( new StoreFactory( $this->getConnection() ) )->getEntityManager();
180
			if ( $this->addDoctrineSubscribers ) {
181
				$entityManager->getEventManager()->addEventSubscriber( $this->newDoctrineDonationPrePersistSubscriber() );
182
				$entityManager->getEventManager()->addEventSubscriber( $this->newDoctrineMembershipApplicationPrePersistSubscriber() );
183
			}
184
185
			return $entityManager;
186
		} );
187
188
		$pimple['subscription_repository'] = $pimple->share( function() {
189
			return new LoggingSubscriptionRepository(
190
				new DoctrineSubscriptionRepository( $this->getEntityManager() ),
191
				$this->getLogger()
192
			);
193
		} );
194
195
		$pimple['donation_repository'] = $pimple->share( function() {
196
			return new LoggingDonationRepository(
197
				new DoctrineDonationRepository( $this->getEntityManager() ),
198
				$this->getLogger()
199
			);
200
		} );
201
202
		$pimple['membership_application_repository'] = $pimple->share( function() {
203
			return new LoggingMembershipApplicationRepository(
204
				new DoctrineMembershipApplicationRepository( $this->getEntityManager() ),
205
				$this->getLogger()
206
			);
207
		} );
208
209
		$pimple['comment_repository'] = $pimple->share( function() {
210
			$finder = new LoggingCommentFinder(
211
				new DoctrineCommentFinder( $this->getEntityManager() ),
212
				$this->getLogger()
213
			);
214
215
			$magicalThinghyOfDoom = new class() extends \PHPUnit_Framework_TestCase {
216
217
				public function createDecorator( $decorated, string $typeName, callable $before, callable $after ) {
218
					/**
219
					 * @var \PHPUnit_Framework_MockObject_MockObject $decorator
220
					 */
221
					$decorator = $this->createMock( $typeName );
222
223
					foreach ( get_class_methods( $typeName ) as $methodName ) {
224
						$decorator->method( $methodName )->willReturnCallback(
225
							function() use ( $decorated, $methodName, $before, $after ) {
226
								call_user_func( $before );
227
								$returnValue = call_user_func_array( [ $decorated, $methodName ], func_get_args() );
228
								call_user_func( $after );
229
230
								return $returnValue;
231
							}
232
						);
233
					}
234
235
					return $decorator;
236
				}
237
			};
238
239
			return $magicalThinghyOfDoom->createDecorator(
240
				$finder,
241
				CommentFinder::class,
242
				function () { $GLOBALS['profiler']->start( 'comment repository' ); },
243
				function () { $GLOBALS['profiler']->stop( 'comment repository' ); }
244
			);
245
		} );
246
247
		$pimple['mail_validator'] = $pimple->share( function() {
248
			return new EmailValidator( new InternetDomainNameValidator() );
249
		} );
250
251
		$pimple['subscription_validator'] = $pimple->share( function() {
252
			return new SubscriptionValidator(
253
				$this->getEmailValidator(),
254
				$this->newTextPolicyValidator( 'fields' ),
255
				$this->newSubscriptionDuplicateValidator(),
256
				$this->newHonorificValidator()
257
			);
258
		} );
259
260
		$pimple['template_name_validator'] = $pimple->share( function() {
261
			return new TemplateNameValidator( $this->getTwig() );
262
		} );
263
264
		$pimple['contact_validator'] = $pimple->share( function() {
265
			return new GetInTouchValidator( $this->getEmailValidator() );
266
		} );
267
268
		$pimple['greeting_generator'] = $pimple->share( function() {
269
			return new GreetingGenerator();
270
		} );
271
272
		$pimple['mw_api'] = $pimple->share( function() {
273
			return new MediawikiApi(
274
				$this->config['cms-wiki-api-url'],
275
				$this->getGuzzleClient()
276
			);
277
		} );
278
279
		$pimple['guzzle_client'] = $pimple->share( function() {
280
			$middlewareFactory = new MiddlewareFactory();
281
			$middlewareFactory->setLogger( $this->getLogger() );
282
283
			$handlerStack = HandlerStack::create( new CurlHandler() );
284
			$handlerStack->push( $middlewareFactory->retry() );
285
286
			return new Client( [
287
				'cookies' => true,
288
				'handler' => $handlerStack,
289
				'headers' => [ 'User-Agent' => 'WMDE Fundraising Frontend' ],
290
			] );
291
		} );
292
293
		$pimple['translator'] = $pimple->share( function() {
294
			$translationFactory = new TranslationFactory();
295
			$loaders = [
296
				'json' => $translationFactory->newJsonLoader()
297
			];
298
			$locale = $this->config['locale'];
299
			$translator = $translationFactory->create( $loaders, $locale );
300
			$translator->addResource( 'json', __DIR__ . '/../../app/translations/messages.' . $locale . '.json', $locale );
301
			$translator->addResource(
302
				'json',
303
				__DIR__ . '/../../app/translations/paymentTypes.' . $locale . '.json',
304
				$locale,
305
				'paymentTypes'
306
			);
307
			$translator->addResource(
308
				'json',
309
				__DIR__ . '/../../app/translations/paymentIntervals.' . $locale . '.json',
310
				$locale,
311
				'paymentIntervals'
312
			);
313
			$translator->addResource(
314
				'json',
315
				__DIR__ . '/../../app/translations/donationStatus.' . $locale . '.json',
316
				$locale,
317
				'donationStatus'
318
			);
319
			$translator->addResource( 'json', __DIR__ . '/../../app/translations/validations.' . $locale . '.json', $locale,
320
				'validations' );
321
			return $translator;
322
		} );
323
324
		// In the future, this could be locale-specific or filled from a DB table
325
		$pimple['honorifics'] = $pimple->share( function() {
326
			return new Honorifics( [
327
				'' => 'Kein Titel',
328
				'Dr.' => 'Dr.',
329
				'Prof.' => 'Prof.',
330
				'Prof. Dr.' => 'Prof. Dr.'
331
			] );
332
		} );
333
334
		$pimple['twig_factory'] = $pimple->share( function () {
335
			return new TwigFactory( $this->config['twig'], $this->getCachePath() . '/twig' );
336
		} );
337
338
		$pimple['twig'] = $pimple->share( function() {
339
			$twigFactory = $this->getTwigFactory();
340
			$loaders = array_filter( [
341
				$twigFactory->newFileSystemLoader(),
342
				$twigFactory->newArrayLoader(), // This is just a fallback for testing
343
				$twigFactory->newWikiPageLoader( $this->newWikiPageRetriever() ),
344
			] );
345
			$extensions = [
346
				$twigFactory->newTranslationExtension( $this->getTranslator() ),
347
				new Twig_Extensions_Extension_Intl()
348
			];
349
350
			return $twigFactory->create( $loaders, $extensions );
351
		} );
352
353
		$pimple['logger'] = $pimple->share( function() {
354
			$logger = new Logger( 'WMDE Fundraising Frontend logger' );
355
356
			$streamHandler = new StreamHandler( $this->newLoggerPath( ( new \DateTime() )->format( 'Y-m-d\TH:i:s\Z' ) ) );
357
			$bufferHandler = new BufferHandler( $streamHandler, 500, Logger::DEBUG, true, true );
358
			$streamHandler->setFormatter( new LineFormatter( "%message%\n" ) );
359
			$logger->pushHandler( $bufferHandler );
360
361
			$errorHandler = new StreamHandler( $this->newLoggerPath( 'error' ), Logger::ERROR );
362
			$errorHandler->setFormatter( new JsonFormatter() );
363
			$logger->pushHandler( $errorHandler );
364
365
			return $logger;
366
		} );
367
368
		$pimple['messenger'] = $pimple->share( function() {
369
			return new Messenger(
370
				new Swift_MailTransport(),
371
				$this->getOperatorAddress(),
372
				$this->config['operator-displayname']
373
			);
374
		} );
375
376
		$pimple['confirmation-page-selector'] = $pimple->share( function() {
377
			return new DonationConfirmationPageSelector( $this->config['confirmation-pages'] );
378
		} );
379
380
		$pimple['paypal-payment-notification-verifier'] = $pimple->share( function() {
381
			return new LoggingPaymentNotificationVerifier(
382
				new PayPalPaymentNotificationVerifier(
383
					new Client(),
384
					$this->config['paypal']
385
				),
386
				$this->getLogger()
387
			);
388
		} );
389
390
		$pimple['credit-card-api-service'] = $pimple->share( function() {
391
			return new McpCreditCardService(
392
				new TNvpServiceDispatcher(
393
					'IMcpCreditcardService_v1_5',
394
					'https://sipg.micropayment.de/public/creditcard/v1.5/nvp/'
395
				),
396
				$this->config['creditcard']['access-key'],
397
				$this->config['creditcard']['testmode']
398
			);
399
		} );
400
401
		$pimple['token_generator'] = $pimple->share( function() {
402
			return new RandomTokenGenerator(
403
				$this->config['token-length'],
404
				new \DateInterval( $this->config['token-validity-timestamp'] )
405
			);
406
		} );
407
408
		$pimple['page_cache'] = $pimple->share( function() {
409
			return new VoidCache();
410
		} );
411
412
		return $pimple;
413
	}
414
415
	public function getConnection(): Connection {
416
		return $this->pimple['dbal_connection'];
417
	}
418
419
	public function getEntityManager(): EntityManager {
420
		return $this->pimple['entity_manager'];
421
	}
422
423
	private function newDonationEventLogger(): DonationEventLogger {
424
		return new BestEffortDonationEventLogger(
425
			new DoctrineDonationEventLogger( $this->getEntityManager() ),
426
			$this->getLogger()
427
		);
428
	}
429
430
	public function newInstaller(): Installer {
431
		return ( new StoreFactory( $this->getConnection() ) )->newInstaller();
432
	}
433
434
	public function newListCommentsUseCase(): ListCommentsUseCase {
435
		return new ListCommentsUseCase( $this->getCommentFinder() );
436
	}
437
438
	public function newCommentListJsonPresenter(): CommentListJsonPresenter {
439
		return new CommentListJsonPresenter();
440
	}
441
442
	public function newCommentListRssPresenter(): CommentListRssPresenter {
443
		return new CommentListRssPresenter( new TwigTemplate(
444
			$this->getTwig(),
445
			'CommentList.rss.twig'
446
		) );
447
	}
448
449
	public function newCommentListHtmlPresenter(): CommentListHtmlPresenter {
450
		return new CommentListHtmlPresenter( $this->getLayoutTemplate( 'CommentList.html.twig' ) );
451
	}
452
453
	private function getCommentFinder(): CommentFinder {
454
		return $this->pimple['comment_repository'];
455
	}
456
457
	public function getSubscriptionRepository(): SubscriptionRepository {
458
		return $this->pimple['subscription_repository'];
459
	}
460
461
	public function setSubscriptionRepository( SubscriptionRepository $subscriptionRepository ) {
462
		$this->pimple['subscription_repository'] = $subscriptionRepository;
463
	}
464
465
	private function getSubscriptionValidator(): SubscriptionValidator {
466
		return $this->pimple['subscription_validator'];
467
	}
468
469
	public function getEmailValidator(): EmailValidator {
470
		return $this->pimple['mail_validator'];
471
	}
472
473
	private function getTemplateNameValidator(): TemplateNameValidator {
474
		return $this->pimple['template_name_validator'];
475
	}
476
477
	public function newDisplayPageUseCase(): DisplayPageUseCase {
478
		return new DisplayPageUseCase(
479
			$this->getTemplateNameValidator()
480
		);
481
	}
482
483
	public function newDisplayPagePresenter(): DisplayPagePresenter {
484
		return new DisplayPagePresenter( $this->getLayoutTemplate( 'DisplayPageLayout.twig' ) );
485
	}
486
487
	public function newAddSubscriptionHTMLPresenter(): AddSubscriptionHtmlPresenter {
488
		return new AddSubscriptionHtmlPresenter( $this->getIncludeTemplate( 'Subscription_Form.twig' ), $this->getTranslator() );
489
	}
490
491
	public function newConfirmSubscriptionHtmlPresenter(): ConfirmSubscriptionHtmlPresenter {
492
		return new ConfirmSubscriptionHtmlPresenter(
493
			$this->getLayoutTemplate( 'ConfirmSubscription.html.twig' ),
494
			$this->getTranslator()
495
		);
496
	}
497
498
	public function newAddSubscriptionJSONPresenter(): AddSubscriptionJsonPresenter {
499
		return new AddSubscriptionJsonPresenter( $this->getTranslator() );
500
	}
501
502
	public function newGetInTouchHTMLPresenter(): GetInTouchHtmlPresenter {
503
		return new GetInTouchHtmlPresenter( $this->getIncludeTemplate( 'Kontaktformular.twig' ), $this->getTranslator() );
504
	}
505
506
	public function getTwig(): Twig_Environment {
507
		return $this->pimple['twig'];
508
	}
509
510
	/**
511
	 * Get a template, with the content for the layout areas filled in.
512
	 *
513
	 * @param string $templateName
514
	 * @return TwigTemplate
515
	 */
516
	private function getLayoutTemplate( string $templateName ): TwigTemplate {
517
		 return new TwigTemplate(
518
			$this->getTwig(),
519
			$templateName,
520
			$this->getDefaultTwigVariables()
521
		);
522
	}
523
524
	/**
525
	 * Get a layouted template that includes another template
526
	 *
527
	 * @param string $templateName Template to include
528
	 * @return TwigTemplate
529
	 */
530
	private function getIncludeTemplate( string $templateName ): TwigTemplate {
531
		return new TwigTemplate(
532
			$this->getTwig(),
533
			'IncludeInLayout.twig',
534
			array_merge(
535
				$this->getDefaultTwigVariables(),
536
				[ 'main_template' => $templateName ]
537
			)
538
		);
539
	}
540
541
	private function getDefaultTwigVariables() {
542
		return [
543
			'basepath' => $this->config['web-basepath'],
544
			'honorifics' => $this->getHonorifics()->getList(),
545
			'header_template' => $this->config['default-layout-templates']['header'],
546
			'footer_template' => $this->config['default-layout-templates']['footer'],
547
			'no_js_notice_template' => $this->config['default-layout-templates']['no-js-notice'],
548
		];
549
	}
550
551
	private function newReferrerGeneralizer() {
552
		return new ReferrerGeneralizer(
553
			$this->config['referrer-generalization']['default'],
554
			$this->config['referrer-generalization']['domain-map']
555
		);
556
	}
557
558
	private function getMediaWikiApi(): MediawikiApi {
559
		return $this->pimple['mw_api'];
560
	}
561
562
	public function setMediaWikiApi( MediawikiApi $api ) {
563
		$this->pimple['mw_api'] = $api;
564
	}
565
566
	private function getGuzzleClient(): ClientInterface {
567
		return $this->pimple['guzzle_client'];
568
	}
569
570
	private function newWikiPageRetriever() {
571
		return new ModifyingPageRetriever(
572
			$this->newCachedPageRetriever(),
573
			$this->newPageContentModifier(),
574
			$this->config['cms-wiki-title-prefix']
575
		);
576
	}
577
578
	private function newCachedPageRetriever(): PageRetriever {
579
		return new CachingPageRetriever(
580
			$this->newNonCachedApiPageRetriever(),
581
			$this->getPageCache()
582
		);
583
	}
584
585
	private function newNonCachedApiPageRetriever(): PageRetriever {
586
		return new ApiBasedPageRetriever(
587
			$this->getMediaWikiApi(),
588
			new ApiUser( $this->config['cms-wiki-user'], $this->config['cms-wiki-password'] ),
589
			$this->getLogger()
590
		);
591
	}
592
593
	public function getLogger(): LoggerInterface {
594
		return $this->pimple['logger'];
595
	}
596
597
	private function newLoggerPath( string $fileName ): string {
598
		return $this->getVarPath() . '/log/' . $fileName . '.log';
599
	}
600
601
	private function getVarPath(): string {
602
		return __DIR__ . '/../../var';
603
	}
604
605
	public function getCachePath(): string {
606
		return $this->getVarPath() . '/cache';
607
	}
608
609
	private function newPageContentModifier(): PageContentModifier {
610
		return new PageContentModifier(
611
			$this->getLogger()
612
		);
613
	}
614
615
	public function newAddSubscriptionUseCase(): AddSubscriptionUseCase {
616
		return new AddSubscriptionUseCase(
617
			$this->getSubscriptionRepository(),
618
			$this->getSubscriptionValidator(),
619
			$this->newAddSubscriptionMailer()
620
		);
621
	}
622
623
	public function newConfirmSubscriptionUseCase(): ConfirmSubscriptionUseCase {
624
		return new ConfirmSubscriptionUseCase(
625
			$this->getSubscriptionRepository(),
626
			$this->newConfirmSubscriptionMailer()
627
		);
628
	}
629
630
	private function newAddSubscriptionMailer(): TemplateBasedMailer {
631
		return $this->newTemplateMailer(
632
			new TwigTemplate(
633
				$this->getTwig(),
634
				'Mail_Subscription_Request.twig',
635
				[
636
					'basepath' => $this->config['web-basepath'],
637
					'greeting_generator' => $this->getGreetingGenerator()
638
				]
639
			),
640
			'mail_subject_membership'
641
		);
642
	}
643
644
	private function newConfirmSubscriptionMailer(): TemplateBasedMailer {
645
		return $this->newTemplateMailer(
646
			new TwigTemplate(
647
					$this->getTwig(),
648
					'Mail_Subscription_Confirmation.twig',
649
					[ 'greeting_generator' => $this->getGreetingGenerator() ]
650
			),
651
			'mail_subject_membership'
652
		);
653
	}
654
655
	private function newTemplateMailer( TwigTemplate $template, string $messageKey ): TemplateBasedMailer {
656
		$mailer = new TemplateBasedMailer(
657
			$this->getMessenger(),
658
			$template,
659
			$this->getTranslator()->trans( $messageKey )
660
		);
661
662
		return new LoggingMailer( $mailer, $this->getLogger() );
663
	}
664
665
	public function getGreetingGenerator() {
666
		return $this->pimple['greeting_generator'];
667
	}
668
669
	public function newCheckIbanUseCase(): CheckIbanUseCase {
670
		return new CheckIbanUseCase( $this->newBankDataConverter() );
671
	}
672
673
	public function newGenerateIbanUseCase(): GenerateIbanUseCase {
674
		return new GenerateIbanUseCase( $this->newBankDataConverter() );
675
	}
676
677
	public function newIbanPresenter(): IbanPresenter {
678
		return new IbanPresenter();
679
	}
680
681
	public function newBankDataConverter() {
682
		return new BankDataConverter( $this->config['bank-data-file'] );
683
	}
684
685
	public function setSubscriptionValidator( SubscriptionValidator $subscriptionValidator ) {
686
		$this->pimple['subscription_validator'] = $subscriptionValidator;
687
	}
688
689
	public function setPageTitlePrefix( string $prefix ) {
690
		$this->config['cms-wiki-title-prefix'] = $prefix;
691
	}
692
693
	public function newGetInTouchUseCase() {
694
		return new GetInTouchUseCase(
695
			$this->getContactValidator(),
696
			$this->getMessenger(),
697
			$this->newContactConfirmationMailer()
698
		);
699
	}
700
701
	private function newContactConfirmationMailer(): TemplateBasedMailer {
702
		return $this->newTemplateMailer(
703
			new TwigTemplate( $this->getTwig(), 'KontaktMailExtern.twig' ),
704
			'mail_subject_getintouch'
705
		);
706
	}
707
708
	private function getContactValidator(): GetInTouchValidator {
709
		return $this->pimple['contact_validator'];
710
	}
711
712
	private function newSubscriptionDuplicateValidator(): SubscriptionDuplicateValidator {
713
		return new SubscriptionDuplicateValidator(
714
				$this->getSubscriptionRepository(),
715
				$this->newSubscriptionDuplicateCutoffDate()
716
		);
717
	}
718
719
	private function newSubscriptionDuplicateCutoffDate(): \DateTime {
720
		$cutoffDateTime = new \DateTime();
721
		$cutoffDateTime->sub( new \DateInterval( $this->config['subscription-interval'] ) );
722
		return $cutoffDateTime;
723
	}
724
725
	private function newHonorificValidator(): AllowedValuesValidator {
726
		return new AllowedValuesValidator( $this->getHonorifics()->getKeys() );
727
	}
728
729
	private function getHonorifics(): Honorifics {
730
		return $this->pimple['honorifics'];
731
	}
732
733
	public function newPurgeCacheUseCase(): PurgeCacheUseCase {
734
		return new PurgeCacheUseCase(
735
			new AllOfTheCachePurger( $this->getTwig(), $this->getPageCache() ),
736
			$this->config['purging-secret']
737
		);
738
	}
739
740
	private function newBankDataValidator(): BankDataValidator {
741
		return new BankDataValidator( new IbanValidator( $this->newBankDataConverter() ) );
742
	}
743
744
	private function getMessenger(): Messenger {
745
		return $this->pimple['messenger'];
746
	}
747
748
	public function setMessenger( Messenger $messenger ) {
749
		$this->pimple['messenger'] = $messenger;
750
	}
751
752
	public function setNullMessenger() {
753
		$this->setMessenger( new Messenger(
754
			Swift_NullTransport::newInstance(),
755
			$this->getOperatorAddress()
756
		) );
757
	}
758
759
	public function getOperatorAddress() {
760
		return new EmailAddress( $this->config['operator-email'] );
761
	}
762
763
	public function newInternalErrorHTMLPresenter(): InternalErrorHtmlPresenter {
764
		return new InternalErrorHtmlPresenter( $this->getIncludeTemplate( 'ErrorPage.twig' ) );
765
	}
766
767
	public function newAccessDeniedHTMLPresenter(): InternalErrorHtmlPresenter {
768
		return new InternalErrorHtmlPresenter( $this->getLayoutTemplate( 'AccessDenied.twig' ) );
769
	}
770
771
	public function getTranslator(): TranslatorInterface {
772
		return $this->pimple['translator'];
773
	}
774
775
	public function setTranslator( TranslatorInterface $translator ) {
776
		$this->pimple['translator'] = $translator;
777
	}
778
779
	private function getTwigFactory(): TwigFactory {
780
		return $this->pimple['twig_factory'];
781
	}
782
783
	private function newTextPolicyValidator( string $policyName ): TextPolicyValidator {
784
		$contentProvider = $this->newWikiPageRetriever();
785
		$textPolicyConfig = $this->config['text-policies'][$policyName];
786
787
		return new TextPolicyValidator(
788
			new PageRetrieverBasedStringList( $contentProvider, $textPolicyConfig['badwords'] ?? '' ),
789
			new PageRetrieverBasedStringList( $contentProvider, $textPolicyConfig['whitewords'] ?? '' )
790
		);
791
	}
792
793
	private function newCommentPolicyValidator(): TextPolicyValidator {
794
		return $this->newTextPolicyValidator( 'comment' );
795
	}
796
797
	public function newCancelDonationUseCase( string $updateToken ): CancelDonationUseCase {
798
		return new CancelDonationUseCase(
799
			$this->getDonationRepository(),
800
			$this->newCancelDonationMailer(),
801
			$this->newDonationAuthorizer( $updateToken ),
802
			$this->newDonationEventLogger()
803
		);
804
	}
805
806
	private function newCancelDonationMailer(): TemplateBasedMailer {
807
		return $this->newTemplateMailer(
808
			new TwigTemplate(
809
				$this->getTwig(),
810
				'Mail_Donation_Cancellation_Confirmation.twig',
811
				[ 'greeting_generator' => $this->getGreetingGenerator() ]
812
			),
813
			'mail_subject_confirm_cancellation'
814
		);
815
	}
816
817
	public function newAddDonationUseCase(): AddDonationUseCase {
818
		return new AddDonationUseCase(
819
			$this->getDonationRepository(),
820
			$this->newDonationValidator(),
821
			$this->newDonationPolicyValidator(),
822
			$this->newReferrerGeneralizer(),
823
			$this->newDonationConfirmationMailer(),
824
			$this->newBankTransferCodeGenerator(),
825
			$this->newDonationTokenFetcher()
826
		);
827
	}
828
829
	private function newBankTransferCodeGenerator(): TransferCodeGenerator {
830
		return new UniqueTransferCodeGenerator(
831
			new SimpleTransferCodeGenerator(),
832
			$this->getEntityManager()
833
		);
834
	}
835
836
	private function newDonationValidator(): AddDonationValidator {
837
		return new AddDonationValidator(
838
			$this->newAmountValidator(),
839
			$this->newBankDataValidator(),
840
			$this->getEmailValidator()
841
		);
842
	}
843
844
	public function newPersonalInfoValidator(): PersonalInfoValidator {
845
		return new PersonalInfoValidator(
846
			new PersonNameValidator(),
847
			new PhysicalAddressValidator(),
848
			$this->getEmailValidator()
849
		);
850
	}
851
852
	private function newDonationConfirmationMailer(): DonationConfirmationMailer {
853
		return new DonationConfirmationMailer(
854
			$this->newTemplateMailer(
855
				new TwigTemplate(
856
					$this->getTwig(),
857
					'Mail_Donation_Confirmation.twig', // TODO: ongoing unification of different templates
858
					[
859
						'basepath' => $this->config['web-basepath'],
860
						'greeting_generator' => $this->getGreetingGenerator()
861
					]
862
				),
863
				'mail_subject_confirm_donation'
864
			)
865
		);
866
	}
867
868
	public function newPayPalUrlGenerator() {
869
		return new PayPalUrlGenerator( $this->getPayPalUrlConfig() );
870
	}
871
872
	private function getPayPalUrlConfig() {
873
		return PayPalUrlConfig::newFromConfig( $this->config['paypal'] );
874
	}
875
876
	private function newCreditCardUrlGenerator() {
877
		return new CreditCardUrlGenerator( $this->newCreditCardUrlConfig() );
878
	}
879
880
	private function newCreditCardUrlConfig() {
881
		return CreditCardUrlConfig::newFromConfig( $this->config['creditcard'] );
882
	}
883
884
	public function getDonationRepository(): DonationRepository {
885
		return $this->pimple['donation_repository'];
886
	}
887
888
	public function newAmountValidator(): AmountValidator {
889
		return new AmountValidator( 1 );
890
	}
891
892
	private function newAmountFormatter(): AmountFormatter {
893
		return new AmountFormatter( $this->config['locale'] );
894
	}
895
896
	public function newDecimalNumberFormatter(): NumberFormatter {
897
		return new NumberFormatter( $this->config['locale'], NumberFormatter::DECIMAL );
898
	}
899
900
	public function newAddCommentUseCase( string $updateToken ): AddCommentUseCase {
901
		return new AddCommentUseCase(
902
			$this->getDonationRepository(),
903
			$this->newDonationAuthorizer( $updateToken ),
904
			$this->newCommentPolicyValidator(),
905
			$this->newAddCommentValidator()
906
		);
907
	}
908
909
	private function newDonationAuthorizer( string $updateToken = null, string $accessToken = null ): DonationAuthorizer {
910
		return new DoctrineDonationAuthorizer(
911
			$this->getEntityManager(),
912
			$updateToken,
913
			$accessToken
914
		);
915
	}
916
917
	public function getTokenGenerator(): TokenGenerator {
918
		return $this->pimple['token_generator'];
919
	}
920
921
	public function newDonationConfirmationPresenter() {
922
		return new DonationConfirmationHtmlPresenter(
923
			$this->getIncludeTemplate( 'DonationConfirmation.twig' )
924
		);
925
	}
926
927
	public function newCreditCardPaymentHtmlPresenter() {
928
		return new CreditCardPaymentHtmlPresenter(
929
			$this->getIncludeTemplate( 'CreditCardPaymentIframe.twig' ),
930
			$this->getTranslator(),
931
			$this->newCreditCardUrlGenerator()
932
		);
933
	}
934
935
	public function newCancelDonationHtmlPresenter() {
936
		return new CancelDonationHtmlPresenter(
937
			$this->getIncludeTemplate( 'Donation_Cancellation_Confirmation.twig' )
938
		);
939
	}
940
941
	public function newApplyForMembershipUseCase(): ApplyForMembershipUseCase {
942
		return new ApplyForMembershipUseCase(
943
			$this->getMembershipApplicationRepository(),
944
			$this->newMembershipApplicationTokenFetcher(),
945
			$this->newApplyForMembershipMailer(),
946
			$this->newMembershipApplicationValidator(),
947
			$this->newMembershipApplicationTracker(),
948
			$this->newMembershipApplicationPiwikTracker()
949
		);
950
	}
951
952
	private function newApplyForMembershipMailer(): TemplateBasedMailer {
953
		return $this->newTemplateMailer(
954
			new TwigTemplate(
955
				$this->getTwig(),
956
				'Mail_Membership_Application_Confirmation.twig',
957
				[ 'greeting_generator' => $this->getGreetingGenerator() ]
958
			),
959
			'mail_subject_confirm_membership_application'
960
		);
961
	}
962
963
	private function newMembershipApplicationValidator(): MembershipApplicationValidator {
964
		return new MembershipApplicationValidator(
965
			new MembershipFeeValidator(),
966
			$this->newBankDataValidator(),
967
			$this->getEmailValidator()
968
		);
969
	}
970
971
	private function newMembershipApplicationTracker(): MembershipApplicationTracker {
972
		return new DoctrineMembershipApplicationTracker( $this->getEntityManager() );
973
	}
974
975
	private function newMembershipApplicationPiwikTracker(): MembershipApplicationPiwikTracker {
976
		return new DoctrineMembershipApplicationPiwikTracker( $this->getEntityManager() );
977
	}
978
979
	public function newCancelMembershipApplicationUseCase( string $updateToken ): CancelMembershipApplicationUseCase {
980
		return new CancelMembershipApplicationUseCase(
981
			$this->newMembershipApplicationAuthorizer( $updateToken ),
982
			$this->getMembershipApplicationRepository(),
983
			$this->newCancelMembershipApplicationMailer()
984
		);
985
	}
986
987
	private function newMembershipApplicationAuthorizer(
988
		string $updateToken = null, string $accessToken = null ): MembershipApplicationAuthorizer {
989
990
		return new DoctrineMembershipApplicationAuthorizer(
991
			$this->getEntityManager(),
992
			$updateToken,
993
			$accessToken
994
		);
995
	}
996
997
	public function getMembershipApplicationRepository(): MembershipApplicationRepository {
998
		return $this->pimple['membership_application_repository'];
999
	}
1000
1001
	private function newCancelMembershipApplicationMailer(): TemplateBasedMailer {
1002
		return $this->newTemplateMailer(
1003
			new TwigTemplate(
1004
				$this->getTwig(),
1005
				'Mail_Membership_Application_Cancellation_Confirmation.twig',
1006
				[ 'greeting_generator' => $this->getGreetingGenerator() ]
1007
			),
1008
			'mail_subject_confirm_membership_application_cancellation'
1009
		);
1010
	}
1011
1012
	public function newMembershipApplicationConfirmationUseCase( string $accessToken ) {
1013
		return new ShowMembershipApplicationConfirmationUseCase(
1014
			$this->newMembershipApplicationAuthorizer( null, $accessToken ), $this->getMembershipApplicationRepository(),
1015
			$this->newMembershipApplicationTokenFetcher()
1016
		);
1017
	}
1018
1019
	public function newShowDonationConfirmationUseCase( string $accessToken ): ShowDonationConfirmationUseCase {
1020
		return new ShowDonationConfirmationUseCase(
1021
			$this->newDonationAuthorizer( null, $accessToken ),
1022
			$this->getDonationRepository()
1023
		);
1024
	}
1025
1026
	public function setDonationConfirmationPageSelector( DonationConfirmationPageSelector $selector ) {
1027
		$this->pimple['confirmation-page-selector'] = $selector;
1028
	}
1029
1030
	public function getDonationConfirmationPageSelector() {
1031
		return $this->pimple['confirmation-page-selector'];
1032
	}
1033
1034
	public function newDonationFormViolationPresenter() {
1035
		$template = $this->getLayoutTemplate( 'DisplayPageLayout.twig' );
1036
		// TODO make this dependent on the 'form' value from the HTTP POST request
1037
		// (we need different form pages for A/B testing)
1038
		$template->context['main_template'] = 'DonationForm.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...
1039
		return new DonationFormViolationPresenter( $template, $this->newAmountFormatter() );
1040
	}
1041
1042
	public function newHandlePayPalPaymentNotificationUseCase( string $updateToken ) {
1043
		return new HandlePayPalPaymentNotificationUseCase(
1044
			$this->getDonationRepository(),
1045
			$this->newDonationAuthorizer( $updateToken ),
1046
			$this->newDonationConfirmationMailer(),
1047
			$this->getLogger(),
1048
			$this->newDonationEventLogger()
1049
		);
1050
	}
1051
1052
	public function getPayPalPaymentNotificationVerifier(): PaymentNotificationVerifier {
1053
		return $this->pimple['paypal-payment-notification-verifier'];
1054
	}
1055
1056
	public function setPayPalPaymentNotificationVerifier( PaymentNotificationVerifier $verifier ) {
1057
		$this->pimple['paypal-payment-notification-verifier'] = $verifier;
1058
	}
1059
1060
	public function newCreditCardNotificationUseCase( string $updateToken ) {
1061
		return new CreditCardNotificationUseCase(
1062
			$this->getDonationRepository(),
1063
			$this->newDonationAuthorizer( $updateToken ),
1064
			$this->getCreditCardService(),
1065
			$this->newDonationConfirmationMailer(),
1066
			$this->getLogger(),
1067
			$this->newDonationEventLogger()
1068
		);
1069
	}
1070
1071
	public function newCancelMembershipApplicationHtmlPresenter() {
1072
		return new CancelMembershipApplicationHtmlPresenter(
1073
			$this->getIncludeTemplate( 'Membership_Application_Cancellation_Confirmation.twig' )
1074
		);
1075
	}
1076
1077
	public function newMembershipApplicationConfirmationHtmlPresenter() {
1078
		return new MembershipApplicationConfirmationHtmlPresenter(
1079
			$this->getIncludeTemplate( 'MembershipApplicationConfirmation.twig' )
1080
		);
1081
	}
1082
1083
	public function newMembershipFormViolationPresenter() {
1084
		return new MembershipFormViolationPresenter(
1085
			$this->getIncludeTemplate( 'MembershipApplication.twig' )
1086
		);
1087
	}
1088
1089
	public function setCreditCardService( CreditCardService $ccService ) {
1090
		$this->pimple['credit-card-api-service'] = $ccService;
1091
	}
1092
1093
	public function getCreditCardService(): CreditCardService {
1094
		return $this->pimple['credit-card-api-service'];
1095
	}
1096
1097
	public function newCreditCardNotificationPresenter(): CreditCardNotificationPresenter {
1098
		return new CreditCardNotificationPresenter(
1099
			new TwigTemplate(
1100
				$this->getTwig(),
1101
				'CreditCardPaymentNotification.twig',
1102
				[ 'returnUrl' => $this->config['creditcard']['return-url'] ]
1103
			)
1104
		);
1105
	}
1106
1107
	private function newDoctrineDonationPrePersistSubscriber(): DoctrineDonationPrePersistSubscriber {
1108
		$tokenGenerator = $this->getTokenGenerator();
1109
		return new DoctrineDonationPrePersistSubscriber(
1110
			$tokenGenerator,
1111
			$tokenGenerator
1112
		);
1113
	}
1114
1115
	private function newDoctrineMembershipApplicationPrePersistSubscriber(): DoctrineMembershipApplicationPrePersistSubscriber {
1116
		$tokenGenerator = $this->getTokenGenerator();
1117
		return new DoctrineMembershipApplicationPrePersistSubscriber(
1118
			$tokenGenerator,
1119
			$tokenGenerator
1120
		);
1121
	}
1122
1123
	public function setTokenGenerator( TokenGenerator $tokenGenerator ) {
1124
		$this->pimple['token_generator'] = $tokenGenerator;
1125
	}
1126
1127
	public function disableDoctrineSubscribers() {
1128
		$this->addDoctrineSubscribers = false;
1129
	}
1130
1131
	private function newDonationTokenFetcher(): DonationTokenFetcher {
1132
		return new DoctrineDonationTokenFetcher(
1133
			$this->getEntityManager()
1134
		);
1135
	}
1136
1137
	private function newMembershipApplicationTokenFetcher(): MembershipApplicationTokenFetcher {
1138
		return new DoctrineMembershipApplicationTokenFetcher(
1139
			$this->getEntityManager()
1140
		);
1141
	}
1142
1143
	private function newDonationPolicyValidator(): AddDonationPolicyValidator {
1144
		return new AddDonationPolicyValidator(
1145
			$this->newDonationAmountPolicyValidator(),
1146
			$this->newTextPolicyValidator( 'fields' )
1147
		);
1148
	}
1149
1150
	private function newDonationAmountPolicyValidator(): AmountPolicyValidator {
1151
		// in the future, this might come from the configuration
1152
		return new AmountPolicyValidator( 1000, 200, 300 );
1153
	}
1154
1155
	public function getDonationTimeframeLimit() {
1156
		return $this->config['donation-timeframe-limit'];
1157
	}
1158
1159
	public function newSystemMessageResponse( string $message ) {
1160
		$test = $this->getIncludeTemplate( 'System_Message.twig' );
1161
		return $test->render( [ 'message' => $message ] );
1162
	}
1163
1164
	public function getMembershipApplicationTimeframeLimit() {
1165
		return $this->config['membership-application-timeframe-limit'];
1166
	}
1167
1168
	private function newAddCommentValidator(): AddCommentValidator {
1169
		return new AddCommentValidator();
1170
	}
1171
1172
	private function getPageCache(): Cache {
1173
		return $this->pimple['page_cache'];
1174
	}
1175
1176
	public function enablePageCache() {
1177
		$this->pimple['page_cache'] = $this->pimple->share( function() {
1178
			return new FilesystemCache( $this->getCachePath() . '/pages' );
1179
		} );
1180
	}
1181
1182
}
1183