Completed
Push — develop ( 0c9847...b22ed9 )
by
unknown
148:24 queued 129:48
created

TemplateController::viewAction()   C

Complexity

Conditions 7
Paths 3

Size

Total Lines 37
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 0 Features 1
Metric Value
c 4
b 0
f 1
dl 0
loc 37
rs 6.7272
cc 7
eloc 23
nc 3
nop 0
1
<?php
2
/**
3
 * YAWIK
4
 *
5
 * @filesource
6
 * @copyright (c) 2013 - 2016 Cross Solution (http://cross-solution.de)
7
 * @author [email protected]
8
 * @license   MIT
9
 */
10
11
namespace Jobs\Controller;
12
13
use Core\Entity\PermissionsInterface;
14
use Jobs\Entity\Status;
15
use Jobs\Repository;
16
use Zend\Mvc\Controller\AbstractActionController;
17
use Zend\View\Model\ViewModel;
18
use Zend\View\Model\JsonModel;
19
use Zend\Stdlib\AbstractOptions;
20
use Zend\Http\PhpEnvironment\Response;
21
22
/**
23
 * Handles rendering the job in formular and in preview mode
24
 *
25
 * Class TemplateController
26
 * @package Jobs\Controller
27
 */
28
class TemplateController extends AbstractActionController
29
{
30
31
    /**
32
     * @var Repository\Job $jobRepository
33
     */
34
    private $jobRepository;
35
36
    /**
37
     * @var AbstractOptions
38
     */
39
    protected $config;
40
41
    public function __construct(Repository\Job $jobRepository, AbstractOptions $config)
42
    {
43
        $this->jobRepository = $jobRepository;
44
        $this->config = $config;
45
    }
46
47
    /**
48
     * Handles the job opening template in preview mode
49
     *
50
     * @return ViewModel
51
     * @throws \RuntimeException
52
     */
53
    public function viewAction()
54
    {
55
        $id = $this->params()->fromQuery('id');
56
        /* @var \Jobs\Entity\Job $job */
57
        $job = $this->jobRepository->find($id);
58
        $services             = $this->getServiceLocator();
59
        $mvcEvent             = $this->getEvent();
60
        $applicationViewModel = $mvcEvent->getViewModel();
61
62
        /* @var \Auth\Entity\User $user */
63
        $user = $this->auth()->getUser();
0 ignored issues
show
Documentation Bug introduced by
The method auth does not exist on object<Jobs\Controller\TemplateController>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
64
65
        /* @var \Zend\View\Model\ViewModel $model */
66
        $model = $services->get('Jobs/viewModelTemplateFilter')->__invoke($job);
67
68
        if ( false &&(
69
            Status::ACTIVE == $job->getStatus() or
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as or instead of || is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
70
            $job->getPermissions()->isGranted($user, PermissionsInterface::PERMISSION_VIEW) or
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as or instead of || is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
71
            $this->auth()->isAdmin()
0 ignored issues
show
Documentation Bug introduced by
The method auth does not exist on object<Jobs\Controller\TemplateController>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
72
        )) {
73
            $applicationViewModel->setTemplate('iframe/iFrameInjection');
74
        }elseif(Status::EXPIRED == $job->getStatus() or  Status::INACTIVE == $job->getStatus()) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as or instead of || is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
75
            $this->response->setStatusCode(Response::STATUS_CODE_410);
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Zend\Stdlib\ResponseInterface as the method setStatusCode() does only exist in the following implementations of said interface: Zend\Http\PhpEnvironment\Response, Zend\Http\Response, Zend\Http\Response\Stream.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
76
            $model->setTemplate('jobs/error/expired');
77
            $model->setVariables(
78
                [
79
                    'job'=>$job,
80
                    'message', 'the job posting you were trying to open, was inactivated or has expired'
81
                ]
82
            );
83
        } else {
84
            // there is a special handling for 404 in ZF2
85
            $this->response->setStatusCode(Response::STATUS_CODE_404);
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Zend\Stdlib\ResponseInterface as the method setStatusCode() does only exist in the following implementations of said interface: Zend\Http\PhpEnvironment\Response, Zend\Http\Response, Zend\Http\Response\Stream.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
86
            $model->setVariable('message', 'job is not available');
87
        }
88
        return $model;
89
    }
90
91
    /**
92
     * Handles the job opening template in formular mode.
93
     *
94
     * All template forms are sending the ID of a job posting and an identifier of the sending
95
     * form.
96
     *
97
     * @return ViewModel
98
     */
99
    protected function editTemplateAction()
100
    {
101
        $id = $this->params('id');
102
        $formIdentifier=$this->params()->fromQuery('form');
103
        $job = $this->jobRepository->find($id);
104
105
        /** @var \Zend\Http\Request $request */
106
        $request              = $this->getRequest();
107
        $isAjax               = $request->isXmlHttpRequest();
108
        $services             = $this->getServiceLocator();
109
        $viewHelperManager    = $services->get('ViewHelperManager');
110
        $mvcEvent             = $this->getEvent();
111
        $applicationViewModel = $mvcEvent->getViewModel();
112
        $forms                = $services->get('FormElementManager');
113
114
        /** @var \Jobs\Form\JobDescriptionTemplate $formTemplate */
115
        $formTemplate         = $forms->get(
116
            'Jobs/Description/Template',
117
            array(
118
            'mode' => $job->id ? 'edit' : 'new'
119
            )
120
        );
121
122
        $formTemplate->setParam('id', $job->id);
123
        $formTemplate->setParam('applyId', $job->applyId);
124
125
        $formTemplate->setEntity($job);
126
127
        if (isset($formIdentifier) && $request->isPost()) {
128
            // at this point the form get instantiated and immediately accumulated
129
130
            $instanceForm = $formTemplate->get($formIdentifier);
131
            if (!isset($instanceForm)) {
132
                throw new \RuntimeException('No form found for "' . $formIdentifier . '"');
133
            }
134
135
            // the id is part of the postData, but it never should be altered
136
            $postData = $request->getPost();
137
138
            unset($postData['id']);
139
            unset($postData['applyId']);
140
141
            $instanceForm->setData($postData);
142
            if ($instanceForm->isValid()) {
143
                $this->getServiceLocator()->get('repositories')->persist($job);
144
            }
145
        }
146
147
        $model = $services->get('Jobs/ViewModelTemplateFilter')->__invoke($formTemplate);
148
149
        if (!$isAjax) {
150
            $basePath   = $viewHelperManager->get('basepath');
151
            $headScript = $viewHelperManager->get('headscript');
152
            $headScript->appendFile($basePath->__invoke('/Core/js/core.forms.js'));
153
        } else {
154
            return new JsonModel(array('valid' => true));
155
        }
156
        $applicationViewModel->setTemplate('iframe/iFrameInjection');
157
        return $model;
158
    }
159
}
160