MapDocCmd   A
last analyzed

Complexity

Total Complexity 6

Size/Duplication

Total Lines 58
Duplicated Lines 36.21 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 6
c 1
b 0
f 0
lcom 1
cbo 4
dl 21
loc 58
rs 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
A getName() 0 3 1
A arrayToObject() 0 3 2
B execute() 21 40 3

How to fix   Duplicated Code   

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:

1
<?php
2
3
4
/**
5
 * @file MapDocCmd.php
6
 * @brief This file contains the MapDocCmd class.
7
 * @details
8
 * @author Filippo F. Fadda
9
 */
10
11
12
namespace EoC\Command;
13
14
15
/**
16
 * @brief Maps a document against every single map function stored into the server.
17
 * @details When the view function is stored in the server, CouchDB starts sending in all the documents in the
18
 * database, one at a time. The server calls the previously stored functions one after another with the document
19
 * and stores its result. When all functions have been called, the result is returned as a JSON string.\n\n
20
 * The argument provided by CouchDB has the following structure:
21
 @code
22
   Array
23
   (
24
       [0] => Array
25
       (
26
           [_id] => 32012
27
           [_rev] => 1-f19919e544340438babac6cc86ec61d5
28
           [title] => Visual Modelling with Rational Rose 2000 and UML
29
       )
30
   )
31
 @endcode
32
 */
33
final class MapDocCmd extends AbstractCmd {
34
  use CmdTrait;
35
36
37
  public static function getName() {
38
    return "map_doc";
39
  }
40
41
42
  // @brief Converts the array to an object.
43
  // @return object
44
  public static function arrayToObject($array) {
45
    return is_array($array) ? (object)array_map(__METHOD__, $array) : $array;
46
  }
47
48
49
  public function execute() {
50
    $doc = self::arrayToObject(reset($this->args));
51
52
    $this->server->getMonolog()->addDebug("MAP ".$doc->_id);
53
54
    // We use a closure here, so we can just expose the emit() function to the closure provided by the user. We have
55
    // another advantage: the $map variable is defined inside execute(), so we don't need to declare it as class member.
56
    $emit = function($key = NULL, $value = NULL) use (&$map) {
0 ignored issues
show
Unused Code introduced by
$emit is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
57
      $map[] = array($key, $value);
58
    };
59
60
    $closure = NULL; // This initialization is made just to prevent a lint error during development.
61
62
    $result = []; // Every time we map a document against all the registered functions we must reset the result.
63
64 View Code Duplication
    foreach ($this->server->getFuncs() as $fn) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
65
      $map = []; // Every time we map a document against a function we must reset the map.
0 ignored issues
show
Bug introduced by
Consider using a different name than the imported variable $map, or did you forget to import by reference?

It seems like you are assigning to a variable which was imported through a use statement which was not imported by reference.

For clarity, we suggest to use a different name or import by reference depending on whether you would like to have the change visibile in outer-scope.

Change not visible in outer-scope

$x = 1;
$callable = function() use ($x) {
    $x = 2; // Not visible in outer scope. If you would like this, how
            // about using a different variable name than $x?
};

$callable();
var_dump($x); // integer(1)

Change visible in outer-scope

$x = 1;
$callable = function() use (&$x) {
    $x = 2;
};

$callable();
var_dump($x); // integer(2)
Loading history...
66
67
      // Here we call the closure function stored in the view. The $closure variable contains the function implementation
68
      // provided by the user. You can have multiple views in a design document and for every single view you can have
69
      // only one map function.
70
      // The closure must be declared like:
71
      //
72
      //     function($doc) use ($emit) { ... };
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...
73
      //
74
      // This technique let you use the syntax '$emit($key, $value);' to emit your record. The function doesn't return
75
      // any value. You don't need to include any files since the closure's code is executed inside this method.
76
      eval("\$closure = ".$fn);
0 ignored issues
show
Coding Style introduced by
It is generally not recommended to use eval unless absolutely required.

On one hand, eval might be exploited by malicious users if they somehow manage to inject dynamic content. On the other hand, with the emergence of faster PHP runtimes like the HHVM, eval prevents some optimization that they perform.

Loading history...
77
78
      if (is_callable($closure)) {
79
        call_user_func($closure, $doc);
80
        $result[] = $map;
81
      }
82
      else
83
        throw new \BadFunctionCallException("The map function is not callable.");
84
    }
85
86
    // Sends mappings to CouchDB.
87
    $this->server->writeln(json_encode($result));
88
  }
89
90
}