Completed
Push — develop ( 7df659...40d27c )
by
unknown
36:05 queued 27:43
created

ImportController   C

Complexity

Total Complexity 42

Size/Duplication

Total Lines 245
Duplicated Lines 3.67 %

Coupling/Cohesion

Components 1
Dependencies 17

Importance

Changes 4
Bugs 2 Features 0
Metric Value
wmc 42
c 4
b 2
f 0
lcom 1
cbo 17
dl 9
loc 245
rs 6.5405

2 Methods

Rating   Name   Duplication   Size   Complexity  
A attachDefaultListeners() 9 9 1
F saveAction() 0 223 41

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like ImportController often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use ImportController, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/**
4
 * YAWIK
5
 *
6
 * @filesource
7
 * @copyright (c) 2013 - 2016 Cross Solution (http://cross-solution.de)
8
 * @license   MIT
9
 */
10
11
/** ActionController of Core */
12
namespace Jobs\Controller;
13
14
use Geo\Entity\Geometry\Point;
15
use Jobs\Entity\Location;
16
use Jobs\Entity\TemplateValues;
17
use Organizations\Entity\Employee;
18
use Zend\Json\Json;
19
use Zend\Mvc\Controller\AbstractActionController;
20
use Zend\View\Model\JsonModel;
21
use Zend\Stdlib\Parameters;
22
use Core\Entity\PermissionsInterface;
23
use Jobs\Listener\Events\JobEvent;
24
use Jobs\Listener\Response\JobResponse;
25
26
/**
27
 *
28
 *
29
 */
30
class ImportController extends AbstractActionController
31
{
32
33
    /**
34
     * attaches further Listeners for generating / processing the output
35
     * @return $this
36
     */
37 View Code Duplication
    public function attachDefaultListeners()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
38
    {
39
        parent::attachDefaultListeners();
40
        $serviceLocator  = $this->serviceLocator;
41
        $defaultServices = $serviceLocator->get('DefaultListeners');
42
        $events          = $this->getEventManager();
43
        $events->attach($defaultServices);
0 ignored issues
show
Documentation introduced by
$defaultServices is of type object|array, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
44
        return $this;
45
    }
46
47
    /**
48
     * api-interface for transferring jobs
49
     * @return JsonModel
50
     */
51
    public function saveAction()
0 ignored issues
show
Coding Style introduced by
saveAction uses the super-global variable $_POST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
52
    {
53
        $services = $this->serviceLocator;
54
55
        /* @var \Zend\Http\PhpEnvironment\Request $request */
56
        $request = $this->getRequest();
57
58
        $params          = $this->params();
59
        $p               = $params->fromPost();
60
        $user            = $services->get('AuthenticationService')->getUser();
61
        $repositories    = $services->get('repositories');
62
        /* @var \Jobs\Repository\Job $repositoriesJob */
63
        $repositoriesJob = $repositories->get('Jobs/Job');
64
        $log             = $services->get('Core/Log');
65
66
        $result = array('token' => session_id(), 'isSaved' => false, 'message' => '', 'portals' => array());
67
        try {
68
            if (isset($user) && !empty($user->login)) {
69
                $formElementManager = $services->get('FormElementManager');
70
                /* @var \Jobs\Form\Import $form */
71
                $form               = $formElementManager->get('Jobs/Import');
72
                $id                 = $params->fromPost('id'); // determine Job from Database
73
                /* @var \Jobs\Entity\Job $entity */
74
                $entity             = null;
75
                $createdJob         = true;
76
77
                if (empty($id)) {
78
                    $applyId = $params->fromPost('applyId');
79
                    if (empty($applyId)) {
80
                        $entity = $repositoriesJob->create();
81
                    } else {
82
                        $entity = $repositoriesJob->findOneBy(array("applyId" => (string) $applyId));
83
                        if (!isset($entity)) {
84
                            // new Job (the more likely branch)
85
                            $entity =$repositoriesJob->create(array("applyId" => (string) $applyId));
86
                        } else {
87
                            $createdJob = false;
88
                        }
89
                    }
90
                } else {
91
                    $repositoriesJob->find($id);
92
                    $createdJob = false;
93
                }
94
                //$services->get('repositories')->get('Jobs/Job')->store($entity);
0 ignored issues
show
Unused Code Comprehensibility introduced by
83% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
95
                $form->bind($entity);
96
                if ($request->isPost()) {
97
                    $loginSuffix                   = '';
98
                    $event                         = $this->getEvent();
99
                    $loginSuffixResponseCollection = $this->getEventManager()->trigger('login.getSuffix', $event);
100
                    if (!$loginSuffixResponseCollection->isEmpty()) {
101
                        $loginSuffix = $loginSuffixResponseCollection->last();
102
                    }
103
                    $params                        = $request->getPost();
104
                    $params->datePublishStart      = \Datetime::createFromFormat("Y-m-d", $params->datePublishStart);
0 ignored issues
show
Bug introduced by
Accessing datePublishStart on the interface Zend\Stdlib\ParametersInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
105
                    $result['post']                = $_POST;
106
                    $form->setData($params);
107
                    if ($form->isValid()) {
108
109
                        if (isset($params['templateValues']['description-description'])) {
110
                            $templateValues = new TemplateValues();
111
                            $entity->setTemplateValues($templateValues->setDescription(strip_tags($params['templateValues']['description-description'])));
112
                        }
113
114
                        $entity->setStatus($params['status']);
115
                        /*
116
                         * Search responsible user via contactEmail
117
                         */
118
                        $users = $repositories->get('Auth/User');
119
                        $responsibleUser = $users->findByEmail($params['contactEmail']);
120
121
                        $entity->setUser($responsibleUser ?: $user);
122
123
                        $group = $user->getGroup($entity->getCompany());
124
                        if ($group) {
125
                            $entity->getPermissions()->grant($group, PermissionsInterface::PERMISSION_VIEW);
126
                        }
127
                        $result['isSaved'] = true;
128
                        $log->info('Jobs/manage/saveJob [user: ' . $user->login . ']:' . var_export($p, true));
129
130
                        if (!empty($params->companyId)) {
0 ignored issues
show
Bug introduced by
Accessing companyId on the interface Zend\Stdlib\ParametersInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
131
                            $companyId                = $params->companyId . $loginSuffix;
0 ignored issues
show
Bug introduced by
Accessing companyId on the interface Zend\Stdlib\ParametersInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
132
                            $repOrganization          = $repositories->get('Organizations/Organization');
133
                            $hydratorManager          = $services->get('hydratorManager');
134
                            /* @var \Organizations\Entity\Hydrator\OrganizationHydrator $hydrator */
135
                            $hydrator                 = $hydratorManager->get('Hydrator/Organization');
136
                            $entityOrganizationFromDB = $repOrganization->findbyRef($companyId);
137
                            //$permissions              = $entityOrganizationFromDB->getPermissions();
0 ignored issues
show
Unused Code Comprehensibility introduced by
60% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
138
                            $data = array(
139
                                'externalId'      => $companyId,
140
                                'organizationName' => $params->company,
0 ignored issues
show
Bug introduced by
Accessing company on the interface Zend\Stdlib\ParametersInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
141
                                'image'            => $params->logoRef,
0 ignored issues
show
Bug introduced by
Accessing logoRef on the interface Zend\Stdlib\ParametersInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
142
                                'user'            => $user
143
                            );
144
                            //$permissions->grant($user, PermissionsInterface::PERMISSION_CHANGE);
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
145
146
                            $entityOrganization = $hydrator->hydrate($data, $entityOrganizationFromDB);
147
                            if ($responsibleUser && $user !== $responsibleUser) {
148
                                /*
149
                                 * We cannot use custom collections yet
150
                                 * @todo if we updated Mongo ODM to >1.0.5, we must move this to
151
                                 *       a custom collection class
152
                                 */
153
                                $employees = $entityOrganization->getEmployees();
154
                                $contained = false;
155
                                /*
156
                                 * this is o(n) and should propably be optimized when the custom collection is created.
157
                                 * It's not very performant to load the whole user entity, when all we need is the ID.
158
                                 * Maybe store the id as reference in the Employees Entity.
159
                                 */
160
                                foreach ($employees as $employee) {
161
                                    if ($employee->getUser()->getId() == $responsibleUser->getId()) {
162
                                        $contained = true;
163
                                        break;
164
                                    }
165
                                }
166
                                if (!$contained) {
167
                                    $employees->add(new Employee($responsibleUser));
168
                                }
169
                            }
170
                            $repositories->store($entityOrganization);
171
                            $entity->setOrganization($entityOrganization);
172
                        } else {
173
                            $result['message'] = '';
174
                        }
175
176
                        if (!empty($params->locations)) {
0 ignored issues
show
Bug introduced by
Accessing locations on the interface Zend\Stdlib\ParametersInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
177
                            $locations = \Zend\Json\Json::decode($params->locations, \Zend\Json\Json::TYPE_ARRAY);
0 ignored issues
show
Bug introduced by
Accessing locations on the interface Zend\Stdlib\ParametersInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
178
                            $jobLocations = $entity->getLocations();
179
                            $jobLocations->clear();
180
                            foreach ($locations as $locData) {
181
                                $location = new Location();
182
                                $coords = array_map(function ($i) { return (float) $i; }, $locData['coordinates']);
183
                                $location->setCountry($locData['country'])
184
                                         ->setRegion($locData['region'])
185
                                         ->setCity($locData['city'])
186
                                         ->setCoordinates(new Point($coords));
187
188
                                $jobLocations->add($location);
189
                            }
190
                        }
191
                        $repositoriesJob->store($entity);
192
                        $id = $entity->getId();
193
                        if (!empty($id)) {
194
                            $jobEvent = $services->get('Jobs/Event');
195
                            $jobEvent->setJobEntity($entity);
196
197
                            $extra = [];
198
                            foreach (array('channels', 'positions', 'branches', 'keywords', 'description') as $paramName) {
199
                                $data = $params->get($paramName);
200
                                if ($data) {
201
                                    $data = Json::decode($data, Json::TYPE_ARRAY);
202
                                    if ('channels' == $paramName) {
203
                                        foreach (array_keys($data) as $portalName) {
204
                                            $jobEvent->addPortal($portalName);
205
                                        }
206
                                    }
207
208
                                    $extra[$paramName] = $data;
209
                                }
210
                            }
211
                            $jobEvent->setParam('extraData', $extra);
212
213
                            if ($createdJob || true) {
214
                                /* @var $jobEvents \Zend\EventManager\EventManager */
215
                                $jobEvents = $services->get('Jobs/Events');
216
                                $jobEvent->setName(JobEvent::EVENT_JOB_ACCEPTED)
217
                                         ->setTarget($this);
218
                                $responses = $jobEvents->trigger($jobEvent);
0 ignored issues
show
Documentation introduced by
$jobEvent is of type object|array, but the function expects a string|object<Zend\EventManager\EventInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
219
                                foreach ($responses as $response) {
220
                                    // responses from the portals
221
                                    // @TODO, put this in some conclusion and meaningful messages
222
                                    if (!empty($response)) {
223
                                        if ($response instanceof JobResponse) {
224
                                            if (!array_key_exists('log', $result)) {
225
                                                $result['log'] = '';
226
                                            }
227
                                            //$message = $response->getMessage();
0 ignored issues
show
Unused Code Comprehensibility introduced by
60% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
228
                                            //$result['log'] .= $response->getMessage() . PHP_EOL;
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
229
                                            $status = $response->getStatus();
230
                                            $portal = $response->getPortal();
231
                                            if (empty($portal)) {
232
                                                throw new \RuntimeException('Publisher-Events (internal error): There is an unregistered publisher listening');
233
                                            }
234
                                            switch ($status) {
235
                                                case JobResponse::RESPONSE_FAIL:
236
                                                case JobResponse::RESPONSE_NOTIMPLEMENTED:
237
                                                case JobResponse::RESPONSE_ERROR:
238
                                                    $result['isSaved'] = false;
239
                                                    break;
240
                                                case JobResponse::RESPONSE_DENIED:
241
                                                case JobResponse::RESPONSE_OK:
242
                                                case JobResponse::RESPONSE_OKANDSTOP:
243
                                                case JobResponse::RESPONSE_DEPRECATED:
244
                                                    break;
245
                                            }
246
                                            if (array_key_exists($portal, $result['portals'])) {
247
                                                throw new \RuntimeException('Publisher-Events (internal error): There are two publisher registered for ' . $portal);
248
                                            }
249
                                            $result['portals'][$portal] = $status;
250
                                        } else {
251
                                            throw new \RuntimeException('Publisher-Events (internal error): Response must be from the class Jobs\Listener\Response\JobResponse');
252
                                        }
253
                                    } else {
254
                                        throw new \RuntimeException('Publisher-Events (internal error): Response must be set');
255
                                    }
256
                                }
257
                            }
258
                        }
259
                    } else {
260
                        $log->info('Jobs/manage/saveJob [error: ' . $form->getMessages() . ']:' . var_export($p, true));
261
                        $result['valid Error'] = $form->getMessages();
262
                    }
263
                }
264
            } else {
265
                $log->info('Jobs/manage/saveJob [error: session lost]:' . var_export($p, true));
266
                $result['message'] = 'session_id is lost';
267
            }
268
        } catch (\Exception $e) {
269
            $result['message'] = 'exception occured: ' . $e->getMessage();
270
        }
271
        //$services->get('Core/Log')->info('Jobs/manage/saveJob result:' . PHP_EOL . var_export($p, True));
0 ignored issues
show
Unused Code Comprehensibility introduced by
58% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
272
        return new JsonModel($result);
273
    }
274
}
275