Completed
Push — develop ( d50679...312a9e )
by
unknown
16:12 queued 08:48
created

TemplateController::viewAction()   B

Complexity

Conditions 4
Paths 2

Size

Total Lines 27
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 27
rs 8.5806
cc 4
eloc 17
nc 2
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
21
/**
22
 * Handles rendering the job in formular and in preview mode
23
 *
24
 * Class TemplateController
25
 * @package Jobs\Controller
26
 */
27
class TemplateController extends AbstractActionController
28
{
29
30
    /**
31
     * @var Repository\Job $jobRepository
32
     */
33
    private $jobRepository;
34
35
    /**
36
     * @var AbstractOptions
37
     */
38
    protected $config;
39
40
    public function __construct(Repository\Job $jobRepository, AbstractOptions $config)
41
    {
42
        $this->jobRepository = $jobRepository;
43
        $this->config = $config;
44
    }
45
46
    /**
47
     * Handles the job opening template in preview mode
48
     *
49
     * @return ViewModel
50
     * @throws \RuntimeException
51
     */
52
    public function viewAction()
53
    {
54
        $id = $this->params()->fromQuery('id');
55
        /* @var \Jobs\Entity\Job $job */
56
        $job = $this->jobRepository->find($id);
57
        $services             = $this->getServiceLocator();
58
        $mvcEvent             = $this->getEvent();
59
        $applicationViewModel = $mvcEvent->getViewModel();
60
61
        /* @var \Auth\Entity\User $user */
62
        $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...
63
64
        $model = $services->get('Jobs/viewModelTemplateFilter')->__invoke($job);
65
66
        if (
67
            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...
68
            $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...
69
            $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...
70
        )
71
        {
72
             $applicationViewModel->setTemplate('iframe/iFrameInjection');
73
        } else {
74
            $this->response->setStatusCode(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...
75
            $model->setVariable('message','job is not available');
76
        }
77
        return $model;
78
    }
79
80
    /**
81
     * Handles the job opening template in formular mode.
82
     *
83
     * All template forms are sending the ID of a job posting and an identifier of the sending
84
     * form.
85
     *
86
     * @return ViewModel
87
     */
88
    protected function editTemplateAction()
89
    {
90
        $id = $this->params('id');
91
        $formIdentifier=$this->params()->fromQuery('form');
92
        $job = $this->jobRepository->find($id);
93
94
        /** @var \Zend\Http\Request $request */
95
        $request              = $this->getRequest();
96
        $isAjax               = $request->isXmlHttpRequest();
97
        $services             = $this->getServiceLocator();
98
        $viewHelperManager    = $services->get('ViewHelperManager');
99
        $mvcEvent             = $this->getEvent();
100
        $applicationViewModel = $mvcEvent->getViewModel();
101
        $forms                = $services->get('FormElementManager');
102
103
        /** @var \Jobs\Form\JobDescriptionTemplate $formTemplate */
104
        $formTemplate         = $forms->get(
105
            'Jobs/Description/Template',
106
            array(
107
            'mode' => $job->id ? 'edit' : 'new'
108
            )
109
        );
110
111
        $formTemplate->setParam('id', $job->id);
112
        $formTemplate->setParam('applyId', $job->applyId);
113
114
        $formTemplate->setEntity($job);
115
116
        if (isset($formIdentifier) && $request->isPost()) {
117
            // at this point the form get instantiated and immediately accumulated
118
119
            $instanceForm = $formTemplate->get($formIdentifier);
120
            if (!isset($instanceForm)) {
121
                throw new \RuntimeException('No form found for "' . $formIdentifier . '"');
122
            }
123
124
            // the id is part of the postData, but it never should be altered
125
            $postData = $request->getPost();
126
127
            unset($postData['id']);
128
            unset($postData['applyId']);
129
130
            $instanceForm->setData($postData);
131
            if ($instanceForm->isValid()) {
132
                $this->getServiceLocator()->get('repositories')->persist($job);
133
            }
134
        }
135
136
        $model = $services->get('Jobs/ViewModelTemplateFilter')->__invoke($formTemplate);
137
138
        if (!$isAjax) {
139
            $basePath   = $viewHelperManager->get('basepath');
140
            $headScript = $viewHelperManager->get('headscript');
141
            $headScript->appendFile($basePath->__invoke('/Core/js/core.forms.js'));
142
        } else {
143
            return new JsonModel(array('valid' => true));
144
        }
145
        $applicationViewModel->setTemplate('iframe/iFrameInjection');
146
        return $model;
147
    }
148
}