Passed
Push — develop ( 28c299...928e2a )
by Mathias
12:40
created

ApplyController::checkApplication()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 2
dl 0
loc 4
c 0
b 0
f 0
ccs 0
cts 4
cp 0
rs 10
cc 1
nc 1
nop 1
crap 2
1
<?php
2
/**
3
 * YAWIK
4
 *
5
 * @filesource
6
 * @copyright (c) 2013 - 2016 Cross Solution (http://cross-solution.de)
7
 * @license   MIT
8
 */
9
10
/** Applications controllers */
11
namespace Applications\Controller;
12
13
use Applications\Entity\Contact;
14
use Applications\Listener\Events\ApplicationEvent;
15
use Core\Factory\ContainerAwareInterface;
16
use Interop\Container\ContainerInterface;
17
use Zend\Mvc\Controller\AbstractActionController;
18
use Zend\Mvc\MvcEvent;
19
use Applications\Entity\Application;
20
use Zend\View\Model\ViewModel;
21
use Zend\View\Model\JsonModel;
22
use Core\Form\Container;
23
use Core\Form\SummaryForm;
24
use Core\Entity\PermissionsInterface;
25
use Applications\Entity\Status;
26
27
/**
28
 * there are basically two ways to use this controller,
29
 * (1) either you have a form, and want to accumulate inputs, or you want to create a form on an existing or new application
30
 * (2) or want to do some action on a concrete form.
31
 *
32
 * for both you need the applyId, which is NOT the application-id, the applyId is an alias for the Job, it can be some human-readable text or an external ID.
33
 * the application to an applyId is found by the combination of the user and the job, that is represented by the applyId.
34
 * this approach ensures, that applications stick to the related job.
35
 *
36
 * nonetheless, there is an exception, for the posts for updating the application, the application-id is needed.
37
 *
38
 * if you use the do as query-parameter, you have to customize the do-Action for the special purpose that is assigned to the do parameter in the query
39
 *
40
 * @method \Acl\Controller\Plugin\Acl acl()
41
 * @method \Core\Controller\Plugin\Notification notification()
42
 * @method \Core\Controller\Plugin\Mailer mailer()
43
 * @method \Auth\Controller\Plugin\Auth auth()
44
 * @author Mathias Gelhausen <[email protected]>
45
 */
46
class ApplyController extends AbstractActionController implements ContainerAwareInterface
47
{
48
    
49
    protected $formContainer;
50
    
51
    protected $config;
52
    
53
    protected $imageCacheManager;
54
    
55
    protected $validator;
56
    
57
    protected $repositories;
58
    
59
    protected $appEvents;
60
    
61
    protected $viewHelper;
62
	
63
	/**
64
	 * @param ContainerInterface $container
65
	 *
66
	 * @return ApplyController
67
	 */
68
    static public function factory(ContainerInterface $container)
69
    {
70
        $ob = new self();
71
        $ob->setContainer($container);
72
        return $ob;
73
    }
74
	
75
	public function setContainer( ContainerInterface $container )
76
	{
77
		$this->config            = $container->get('Config');
78
		$this->imageCacheManager = $container->get('Organizations\ImageFileCache\Manager');
79
		$this->validator         = $container->get('ValidatorManager');
80
		$this->repositories      = $container->get('repositories');
81
		$this->appEvents         = $container->get('Applications/Events');
82
		$this->viewHelper        = $container->get('ViewHelperManager');
83
	}
84
	
85
	
86
	public function attachDefaultListeners()
87
	{
88
		parent::attachDefaultListeners();
89
		$events = $this->getEventManager();
90
		$events->attach(MvcEvent::EVENT_DISPATCH, array($this, 'preDispatch'), 10);
91
		return $this;
92
	}
93
	
94
    public function preDispatch(MvcEvent $e)
95
    {
96
        /* @var $application \Applications\Entity\Application */
97
        if ($this->params()->fromQuery('do')) {
98
            $e->getRouteMatch()->setParam('action', 'do');
99
            return;
100
        }
101
102
        /* @var $request    \Zend\Http\Request */
103
        /* @var $repository \Applications\Repository\Application */
104
        /* @var $container  \Applications\Form\Apply */
105
        $request      = $this->getRequest();
106
        $services     = $e->getApplication()->getServiceManager();
107
        $repositories = $services->get('repositories');
108
        $repository   = $repositories->get('Applications/Application');
109
        $container    = $services->get('forms')->get('Applications/Apply');
110
        
111
        if ($request->isPost()) {
0 ignored issues
show
Bug introduced by
The method isPost() does not exist on Zend\Stdlib\RequestInterface. It seems like you code against a sub-type of Zend\Stdlib\RequestInterface such as Zend\Http\Request. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

111
        if ($request->/** @scrutinizer ignore-call */ isPost()) {
Loading history...
112
            $appId = $this->params()->fromPost('applicationId');
113
            if (!$appId) {
114
                throw new \RuntimeException('Missing application id.');
115
            }
116
            $routeMatch = $e->getRouteMatch();
117
118
            if ('recruiter-preview' == $appId) {
119
                $routeMatch->setParam('action', 'process-preview');
120
                return;
121
            }
122
123
            $application = $repository->find($appId);
124
            if (!$application) {
125
                throw new \RuntimeException('Invalid application id.');
126
            }
127
128
            $action     = 'process';
129
130
            $routeMatch->setParam('action', $action);
131
        } else {
132
            $user  = $this->auth()->getUser();
133
            $appId = $this->params('applyId');
134
            if (!$appId) {
135
                throw new \RuntimeException('Missing apply id');
136
            }
137
138
            /* @var \Jobs\Entity\Job $job */
139
            $job = $repositories->get('Jobs/Job')->findOneByApplyId($appId);
140
141
            if (!$job) {
0 ignored issues
show
introduced by
$job is of type Jobs\Entity\Job, thus it always evaluated to true.
Loading history...
142
                $e->getRouteMatch()->setParam('action', 'job-not-found');
143
                return;
144
            }
145
146
            switch ($job->getStatus()) {
147
                case \Jobs\Entity\Status::ACTIVE:
148
                    break;
149
                default:
150
                    $e->getRouteMatch()->setParam('action', 'job-not-found');
151
                    return;
152
                    break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
153
            }
154
155
            if ($user === $job->getUser()) {
156
                $application = new \Applications\Entity\Application();
157
                $application->setContact(new Contact());
158
                $application->setJob($job);
159
                $application->setId('recruiter-preview');
160
            } else {
161
                $subscriberUri = $this->params()->fromQuery('subscriber');
162
                $application   = $repository->findDraft($user, $appId);
163
164
                if ($application) {
165
                    /* @var $form \Auth\Form\UserInfo */
166
                    $form = $container->getForm('contact.contact');
167
                    $form->setDisplayMode('summary');
168
169
                    if ($subscriberUri) {
170
                        $subscriber = $application->getSubscriber();
171
                        if (!$subscriber || $subscriber->uri != $subscriberUri) {
172
                            $subscriber = $repositories->get('Applications/Subscriber')->findbyUri($subscriberUri, /*create*/ true);
173
                            $application->setSubscriber($subscriber);
174
                            $subscriber->getname();
175
                        }
176
                    }
177
                } else {
178
                    if (!$job) {
179
                        $e->getRouteMatch()->setParam('action', 'job-not-found');
180
                        return;
181
                    }
182
                    if ($job->getUriApply()) {
183
                        return $this->redirect($job->getUriApply());
184
                    }
185
186
                    /* @var $application \Applications\Entity\Application */
187
                    $application = $repository->create();
188
                    $application->setIsDraft(true)
189
                                ->setContact($user->getInfo())
190
                                ->setUser($user)
191
                                ->setJob($job);
192
193
                    if ($subscriberUri) {
194
                        $subscriber = $repositories->get('Applications/Subscriber')->findbyUri($subscriberUri, /*create*/ true);
195
                        $application->setSubscriber($subscriber);
196
                    }
197
198
                    $repositories->store($application);
199
                    /*
200
                     * If we had copy an user image, we need to refresh its data
201
                     * to populate the length property.
202
                     */
203
                    if ($image = $application->getContact()->getImage()) {
204
                        $repositories->refresh($image);
205
                    }
206
                }
207
            }
208
        }
209
        
210
        $container->setEntity($application);
211
        $this->configureContainer($container);
212
        $this->formContainer     = $container;
213
    }
214
    
215
    public function jobNotFoundAction()
216
    {
217
        $this->response->setStatusCode(410);
0 ignored issues
show
Bug introduced by
The method setStatusCode() does not exist on Zend\Stdlib\ResponseInterface. It seems like you code against a sub-type of Zend\Stdlib\ResponseInterface such as Zend\Http\Response. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

217
        $this->response->/** @scrutinizer ignore-call */ 
218
                         setStatusCode(410);
Loading history...
218
        $model = new ViewModel(
219
            [ 'content' => /*@translate*/ 'Invalid apply id']
220
        );
221
        $model->setTemplate('applications/error/not-found');
222
        return $model;
223
    }
224
    
225
    public function indexAction()
226
    {
227
        /* @var \Applications\Form\Apply $form */
228
        $form        = $this->formContainer;
229
        $application = $form->getEntity(); /* @var \Applications\Entity\Application $application */
230
        
231
        $form->setParam('applicationId', $application->getId());
232
233
        $organizationImageCache = $this->imageCacheManager;
234
235
        $model = new ViewModel(
236
            [
237
            'form' => $form,
238
            'isApplicationValid' => $this->checkApplication($application),
239
            'application' => $application,
240
            'organizationImageCache' =>  $organizationImageCache
241
            ]
242
        );
243
        $model->setTemplate('applications/apply/index');
244
        return $model;
245
    }
246
    
247
    public function oneClickApplyAction()
248
    {
249
        /* @var \Applications\Entity\Application $application */
250
        $application = $this->formContainer->getEntity();
251
        $job = $application->getJob();
252
        $atsMode = $job->getAtsMode();
253
        
254
        // check for one click apply
255
        if (!($atsMode->isIntern() && $atsMode->getOneClickApply()))
256
        {
257
            // redirect to regular application
258
            return $this->redirect()
259
                ->toRoute('lang/apply', ['applyId' => $job->getApplyId()]);
260
        }
261
        
262
        $network = $this->params('network');
263
264
        $hybridAuth = $this->formContainer
265
            ->get('HybridAuthAdapter')
266
            ->getHybridAuth();
267
        /* @var $authProfile \Hybrid_User_Profile */
268
        $authProfile = $hybridAuth->authenticate($network)
269
           ->getUserProfile();
270
271
        /* @var \Auth\Entity\SocialProfiles\AbstractProfile $profile */
272
        $profile = $this->plugin('Auth/SocialProfiles')->fetch($network);
0 ignored issues
show
Bug introduced by
The method fetch() does not exist on Zend\Stdlib\DispatchableInterface. It seems like you code against a sub-type of Zend\Stdlib\DispatchableInterface such as Zend\Mvc\Controller\AbstractController. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

272
        $profile = $this->plugin('Auth/SocialProfiles')->/** @scrutinizer ignore-call */ fetch($network);
Loading history...
273
274
        $contact = $application->getContact();
275
        $contact->setEmail($authProfile->emailVerified ?: $authProfile->email);
276
        $contact->setFirstName($authProfile->firstName);
277
        $contact->setLastName($authProfile->lastName);
278
        $contact->setBirthDay($authProfile->birthDay);
279
        $contact->setBirthMonth($authProfile->birthMonth);
280
        $contact->setBirthYear($authProfile->birthYear);
281
        $contact->setPostalCode($authProfile->zip);
282
        $contact->setCity($authProfile->city);
283
        $contact->setStreet($authProfile->address);
284
        $contact->setPhone($authProfile->phone);
285
        $contact->setGender($authProfile->gender);
286
287
        $profiles = $application->getProfiles();
288
        $profiles->add($profile);
289
290
        $cv = $application->getCv();
291
        $cv->setEmployments($profile->getEmployments());
292
        $cv->setEducations($profile->getEducations());
293
294
        if ($authProfile->photoURL)
295
        {
296
            $response = (new \Zend\Http\Client($authProfile->photoURL, ['sslverifypeer' => false]))->send();
297
            $file = new \Doctrine\MongoDB\GridFSFile();
298
            $file->setBytes($response->getBody());
299
            
300
            $image = new \Applications\Entity\Attachment();
301
            $image->setName($contact->getLastName().$contact->getFirstName());
302
            $image->setType($response->getHeaders()->get('Content-Type')->getFieldValue());
0 ignored issues
show
Bug introduced by
The method getFieldValue() does not exist on ArrayIterator. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

302
            $image->setType($response->getHeaders()->get('Content-Type')->/** @scrutinizer ignore-call */ getFieldValue());

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
303
            $image->setFile($file);
304
            $image->setPermissions($application->getPermissions());
305
            
306
            $contact->setImage($image);
307
        }
308
        
309
        $urlOptions = [];
310
        
311
        if ($this->params('immediately'))
312
        {
313
            $application->getAttributes()->setAcceptedPrivacyPolicy(true);
314
            $urlOptions = [
315
                'query' => [
316
                    'do' => 'send'
317
                ]
318
            ];
319
        }
320
        
321
        return $this->redirect()
322
           ->toRoute('lang/apply', ['applyId' => $job->getApplyId()], $urlOptions);
323
    }
324
325
    public function processPreviewAction()
326
    {
327
        return new JsonModel(array('valid' => false, 'errors' => array()));
328
    }
329
    
330
    public function processAction()
331
    {
332
    	$params = $this->params();
333
        $formName  = $params->fromQuery('form');
334
        $form      = $this->formContainer->getForm($formName);
335
        $postData  = $form->getOption('use_post_array') ? $params->fromPost() : array();
336
	    //@TODO: [ZF3] option use_files_array is false by default
337
        //$filesData = $form->getOption('use_files_array') ? $params->fromFiles() : array();
338
        $form->setData(array_merge($postData,$_FILES));
339
        
340
        if (!$form->isValid()) {
341
            return new JsonModel(
342
                array(
343
                'valid' => false,
344
                'errors' => $form->getMessages(),
345
                )
346
            );
347
        }
348
        $application = $this->formContainer->getEntity();
349
        $this->repositories->store($application);
350
        
351
        if ('file-uri' === $params->fromPost('return')) {
352
            $basepath = $this->viewHelper->get('basepath');
353
            $content = $basepath($form->getHydrator()->getLastUploadedFile()->getUri());
354
        } else {
355
            if ($form instanceof SummaryForm) {
356
                $form->setRenderMode(SummaryForm::RENDER_SUMMARY);
357
                $viewHelper = 'summaryForm';
358
            } else {
359
                $viewHelper = 'form';
360
            }
361
            $content = $this->viewHelper->get($viewHelper)->__invoke($form);
362
        }
363
        
364
        return new JsonModel(
365
            array(
366
	            'valid' => $form->isValid(),
367
	            'content' => $content,
368
	            'isApplicationValid' => $this->checkApplication($application)
369
            )
370
        );
371
    }
372
    
373
    public function doAction()
374
    {
375
        $config       = $this->config;
376
        $repositories = $this->repositories;
377
        $repository   = $repositories->get('Applications/Application');
378
        $organizationImageCache = $this->imageCacheManager;
379
        /* @var Application $application*/
380
        $application  = $repository->findDraft(
381
            $this->auth()->getUser(),
382
            $this->params('applyId')
383
        );
384
        
385
        if (!$application) {
0 ignored issues
show
introduced by
$application is of type Applications\Entity\Application, thus it always evaluated to true.
Loading history...
386
            throw new \Exception('No application draft found.');
387
        }
388
        
389
        if ('abort' == $this->params()->fromQuery('do')) {
390
            $repositories->remove($application);
391
            return $this->redirect()->toRoute('lang/apply', array('applyId' => $this->params('applyId')));
392
        }
393
        
394
        if (!$this->checkApplication($application)) {
395
            $this->notification()->error(/*@translate*/ 'There are missing required informations. Your application cannot be send.');
396
            return $this->redirect()->toRoute('lang/apply', array('applyId' => $this->params('applyId')));
397
        }
398
399
        if ('previewmail' == $this->params()->fromQuery('do')) {
400
            $this->mailer('Applications/CarbonCopy', [ 'application' => $application], true);
0 ignored issues
show
Unused Code introduced by
The call to Applications\Controller\ApplyController::mailer() has too many arguments starting with 'Applications/CarbonCopy'. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

400
            $this->/** @scrutinizer ignore-call */ 
401
                   mailer('Applications/CarbonCopy', [ 'application' => $application], true);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
401
            $this->notification()->success(/*@translate*/ 'Mail has been send');
402
            return new JsonModel();
403
        }
404
405
        if ('sendmail' == $this->params()->fromQuery('do')) {
406
            $jobEntity         = $application->getJob();
407
408
            $mailData = array(
409
                'application' => $application,
410
                'to'          => $jobEntity->getContactEmail()
411
            );
412
            if (array_key_exists('mails', $config) && array_key_exists('from', $config['mails']) && array_key_exists('email', $config['mails']['from'])) {
413
                $mailData['from'] = $config['mails']['from']['email'];
414
            }
415
            $this->mailer('Applications/CarbonCopy', $mailData, true);
416
            $repositories->remove($application);
417
            //$this->notification()->success(/*@translate*/ 'Application has been send.');
418
            $model = new ViewModel(
419
                array(
420
                'organizationImageCache' =>  $organizationImageCache,
421
                'success' => true,
422
                'job' => $jobEntity,
423
                )
424
            );
425
            $model->setTemplate('applications/apply/success');
426
            return $model;
427
        }
428
429
        $application->setIsDraft(false)
430
            ->setStatus(new Status())
431
            ->getPermissions()
432
            ->revoke($this->auth()->getUser(), PermissionsInterface::PERMISSION_CHANGE)
433
            ->inherit($application->getJob()->getPermissions());
434
435
        $repositories->store($application);
436
        
437
        $events   = $this->appEvents;
438
        $events->trigger(ApplicationEvent::EVENT_APPLICATION_POST_CREATE, $this, [ 'application' => $application ]);
439
440
        $model = new ViewModel(
441
            array(
442
            'success' => true,
443
            'application' => $application,
444
            'organizationImageCache' =>  $organizationImageCache,
445
            )
446
        );
447
        $model->setTemplate('applications/apply/index');
448
449
        return $model;
450
    }
451
452
    protected function checkApplication($application)
453
    {
454
        return $this->validator->get('Applications/Application')
455
                    ->isValid($application);
456
    }
457
458
    /**
459
     * Configures the apply form container.
460
     *
461
     * Currently only disables elements.
462
     *
463
     * @param Container $container
464
     */
465
    protected function configureContainer(Container $container)
466
    {
467
        /* @var $application Application */
468
        $application = $container->getEntity();
469
        $job         = $application->getJob();
470
471
        /** @var $settings \Applications\Entity\Settings */
472
        $settings = ($user = $job->getUser()) ? $user->getSettings('Applications') : null;
473
        $formSettings = $settings ? $settings->getApplyFormSettings() : null;
0 ignored issues
show
introduced by
$settings is of type Applications\Entity\Settings, thus it always evaluated to true.
Loading history...
474
475
        if ($formSettings && $formSettings->isActive()) {
476
            $container->disableElements($formSettings->getDisableElements());
477
            return;
478
        }
479
480
        $config = $this->config;
481
        $config = isset($config['form_elements_config']['Applications/Apply']['disable_elements'])
482
                ? $config['form_elements_config']['Applications/Apply']['disable_elements']
483
                : null;
484
        if ($config) {
485
            $container->disableElements($config);
486
        }
487
    }
488
}
489