Completed
Push — 8.x-2.x ( 8ecf3f...eae9c1 )
by Frédéric G.
02:53
created

modules/mongodb_watchdog/mongodb_watchdog.module::mongodb_watchdog_watchdog()   C

Complexity

Conditions 8
Paths 25

Size

Total Lines 63
Code Lines 47

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
cc 8
eloc 47
c 4
b 0
f 0
nc 25
nop 1
dl 0
loc 63
rs 6.8825

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * @file
5
 * Fires watchdog messages to mongodb.
6
 */
7
8
/* ==== Everything below this line is broken ================================ */
9
10
/**
11
 * Implements hook_menu().
12
 */
13
function mongodb_watchdog_menu() {
14
  $items['admin/reports/mongodb'] = array(
0 ignored issues
show
Coding Style Comprehensibility introduced by
$items was never initialized. Although not strictly required by PHP, it is generally a good practice to add $items = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
15
    'title' => 'Recent log entries in MongoDB',
16
    'description' => 'View events that have recently been logged in MongoDB.',
17
    'page callback' => 'mongodb_watchdog_overview',
18
    'access arguments' => array('access site reports'),
19
    'file'  => 'mongodb_watchdog.admin.inc',
20
  );
21
  $items['admin/reports/mongodb/%mongodb_watchdog_event'] = array(
22
    'title' => 'MongoDB log details',
23
    'page callback' => 'mongodb_watchdog_event',
24
    'page arguments' => array(3),
25
    'access arguments' => array('access site reports'),
26
    'type' => MENU_CALLBACK,
27
    'file' => 'mongodb_watchdog.admin.inc',
28
  );
29
  $items['admin/reports/mongodb/list'] = array(
30
    'type' => MENU_DEFAULT_LOCAL_TASK,
31
    'title' => 'Overview',
32
  );
33
  $items['admin/reports/mongodb/access-denied'] = array(
34
    'type' => MENU_LOCAL_TASK,
35
    'title' => "Top 'access denied' errors in MongoDB",
36
    'description' => "View 'access denied' errors (403s).",
37
    'page callback' => 'mongodb_watchdog_page_top',
38
    'page arguments' => array('access denied'),
39
    'access arguments' => array('access site reports'),
40
    'file' => 'mongodb_watchdog.admin.inc',
41
  );
42
  $items['admin/reports/mongodb/page-not-found'] = array(
43
    'type' => MENU_LOCAL_TASK,
44
    'title' => "Top 'page not found' errors in MongoDB",
45
    'description' => "View 'page not found' errors (404s).",
46
    'page callback' => 'mongodb_watchdog_page_top',
47
    'page arguments' => array('page not found'),
48
    'access arguments' => array('access site reports'),
49
    'file' => 'mongodb_watchdog.admin.inc',
50
  );
51
52
  return $items;
53
}
54
55
/**
56
 * Load a MongoDB watchdog event.
57
 *
58
 * @param string $id
59
 *   The event id.
60
 *
61
 * @return object|false
62
 *   A loaded event.
63
 */
64
function mongodb_watchdog_event_load($id) {
65
  $result = mongodb_collection(variable_get('mongodb_watchdog', 'watchdog'))
0 ignored issues
show
Bug introduced by
The method findOne does only exist in MongoCollection, but not in MongoDebugCollection and MongoDummy.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
66
    ->findOne(array('_id' => $id));
67
  return $result ? $result : FALSE;
68
}
69
70
/**
71
 * Implements hook_watchdog().
72
 *
73
 * Refer to issue #1355808 regarding filtering.
74
 *
75
 * @link http://drupal.org/node/1355808 @endlink
76
 */
77
function mongodb_watchdog_watchdog(array $log_entry) {
78
  $watchdog_limit = variable_get('watchdog_limit', WATCHDOG_DEBUG);
79
  if (isset($log_entry['severity']) && $log_entry['severity'] > $watchdog_limit) {
80
    return;
81
  }
82
83
  static $checked_ids = array();
84
85
  // Find the function that generated this error.
86
  $log_entry = (array) $log_entry;
87
  _mongodb_watchdog_enhance_log_entry($log_entry, debug_backtrace());
88
  $account = $log_entry['user'];
89
  // Special handling for core bug #904994:
90
  if (!isset($log_entry['variables'])) {
91
    $special_messages = array(
92
      'page not found' => 'Page not found: @param',
93
      'access denied'  => 'Access denied: @param',
94
    );
95
    $type = $log_entry['type'];
96
    $log_entry['variables'] = array('@param' => $log_entry['message']);
97
    $log_entry['message'] = isset($special_messages[$type])
98
      ? $special_messages[$log_entry['type']]
99
      : '@param';
100
  }
101
102
  $event = array(
103
    'variables' => $log_entry['variables'],
104
    'timestamp' => $log_entry['timestamp'],
105
    'user' => array(
106
      'name' => isset($account->name) ? $account->name : variable_get('anonymous', t('Anonymous')),
107
      'uid' => $log_entry['uid'],
108
    ),
109
    'ip' => $log_entry['ip'],
110
    'request_uri' => $log_entry['request_uri'],
111
    'referer' => $log_entry['referer'],
112
    'link' => $log_entry['link'],
113
  );
114
  unset($log_entry['variables'], $log_entry['user'], $log_entry['ip'], $log_entry['request_uri'], $log_entry['referer'], $log_entry['link']);
115
116
  $newobj = array(
117
    '$set' => $log_entry,
118
    '$inc' => array('count' => 1),
119
  );
120
  $collection = mongodb_collection(variable_get('mongodb_watchdog', 'watchdog'));
121
  $id = md5($log_entry['function'] . ':' . $log_entry['line'] . ':' . $log_entry['severity'] . ':' . $log_entry['type'] . ':' . $log_entry['message']);
122
  if (!isset($checked_ids[$id])) {
123
    $checked_ids[$id] = $collection->findOne(array('_id' => $id), array('_id' => 1));
0 ignored issues
show
Bug introduced by
The method findOne does only exist in MongoCollection, but not in MongoDebugCollection and MongoDummy.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
124
  }
125
  $collection->update(array('_id' => $id), $newobj, array('upsert' => TRUE) + mongodb_default_write_options(FALSE));
0 ignored issues
show
Bug introduced by
The method update does only exist in MongoCollection, but not in MongoDebugCollection and MongoDummy.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
126
  $collection = $collection->db->selectCollection('watchdog_event_' . $id);
127
  if (empty($checked_ids[$id])) {
128
    $max = variable_get('mongodb_watchdog_items', 10000);
129
    $command = array(
130
      'create' => $collection->getName(),
131
      'capped' => TRUE,
132
      'size' => $max * 1000,
133
      "max" => $max,
134
    );
135
    $collection->db->command($command);
136
    $checked_ids[$id] = TRUE;
137
  }
138
  $collection->insert($event, mongodb_default_write_options(FALSE));
139
}
140
141
/**
142
 * Fill in the log_entry function, file, and line.
143
 *
144
 * @param array $log_entry
145
 *   An event information to be logger.
146
 * @param array $backtrace
147
 *   A call stack.
148
 */
149
function _mongodb_watchdog_enhance_log_entry(&$log_entry, $backtrace) {
150
  // Create list of functions to ignore in backtrace.
151
  static $ignore = array(
152
    'mongodb_watchdog_watchdog' => 1,
153
    'call_user_func_array' => 1,
154
    'module_invoke' => 1,
155
    'watchdog' => 1,
156
    '_drupal_log_error' => 1,
157
    '_drupal_error_handler' => 1,
158
    '_drupal_error_handler_real' => 1,
159
    'theme_render_template' => 1,
160
  );
161
162
  foreach ($backtrace as $bt) {
163
    if (isset($bt['function'])) {
164
      if (isset($bt['line']) && !isset($ignore[$bt['function']])) {
165
        if (isset($bt['file'])) {
166
          $log_entry['file'] = $bt['file'];
167
        }
168
        $log_entry['function'] = $bt['function'];
169
        $log_entry['line'] = $bt['line'];
170
        break;
171
      }
172
      elseif ($bt['function'] == '_drupal_exception_handler') {
173
        $e = $bt['args'][0];
174
        _mongodb_watchdog_enhance_log_entry($log_entry, $e->getTrace());
175
      }
176
    }
177
  }
178
}
179