Failed Conditions
Push — master ( c3e11c...1d8d9e )
by Yo
02:09 queued 37s
created

server/plugin.js   F

Complexity

Total Complexity 89
Complexity/F 2.54

Size

Lines of Code 440
Function Count 35

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 0
nc 96
dl 0
loc 440
rs 3.12
c 1
b 0
f 0
wmc 89
mnd 3
bc 76
fnc 35
bpm 2.1714
cpm 2.5428
noi 51

27 Functions

Rating   Name   Duplication   Size   Complexity  
B plugin.js ➔ refresh 0 30 6
B Router.post(ꞌ/plugin/config/:nameꞌ) 0 25 5
A plugin.js ➔ exists 0 4 2
A plugin.js ➔ sort 0 11 3
A plugin.js ➔ socket 0 10 1
A Router.all(ꞌ/plugin/sortꞌ) 0 5 1
A Router.get(ꞌ/plugin/help/:nameꞌ) 0 9 3
A Router.get(ꞌ/plugin/github/:nameꞌ) 0 9 1
A Router.all(ꞌ/plugin/:name*ꞌ) 0 11 3
A plugin.js ➔ find 0 3 1
A plugin.js ➔ trigger 0 3 1
A Plugin.getLocale 0 12 4
A plugin.js ➔ init 0 8 1
A plugin.js ➔ listen 0 3 1
A require.uncache 0 7 1
A Router.get(ꞌ/plugin/edit/:nameꞌ) 0 5 1
A require.searchCache 0 21 3
D Plugin.getInstance 0 35 10
B Router.all(ꞌ/plugin/:name/*ꞌ) 0 20 5
A Router.all(ꞌ/static/:name/*ꞌ) 0 9 3
A plugin.js ➔ remove 0 14 3
B plugin.js ➔ getList 0 29 4
A plugin.js ➔ getCache 0 1 1
A Plugin.isDisabled 0 4 2
A plugin.js ➔ getLocales 0 10 3
A Router.get(ꞌ/plugin/config/:nameꞌ) 0 4 1
B plugin.js ➔ Plugin 0 28 4

How to fix   Complexity   

Complexity

Complex classes like server/plugin.js 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.

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.

1
var fs      = require('fs-extra');
2
var request = require('request');
3
var express = require('express');
4
var extend  = require('extend');
5
6
// ------------------------------------------
7
//  CONSTRUCTOR
8
// ------------------------------------------
9
10
var init = function(){
11
  info('Starting PluginManager ...');
12
  
13
  // Refresh local plugins
14
  refresh();
15
  
16
  return PluginManager;
17
}
18
19
// ------------------------------------------
20
//  HELPER: REQUIRE 
21
// ------------------------------------------
22
23
/**
24
 * Removes a module from the cache
25
 */
26
require.uncache = function (moduleName) {
27
  // Run over the cache looking for the files
28
  // loaded by the specified module name
29
  require.searchCache(moduleName, function (mod) {
30
    delete require.cache[mod.id];
31
  });
32
};
33
34
/**
35
 * Runs over the cache to search for all the cached files
36
 */
37
require.searchCache = function (moduleName, callback) {
38
  // Resolve the module identified by the specified name
39
  var mod = require.resolve(moduleName);
40
41
  // Check if the module has been resolved and found within
42
  // the cache
43
  if (mod && ((mod = require.cache[mod]) !== undefined)) {
44
    // Recursively go over the results
45
    (function run(mod) {
46
      // Go over each of the module's children and
47
      // run over it
48
      mod.children.forEach(function (child) {
49
          run(child);
50
      });
51
52
      // Call the specified callback providing the
53
      // found module
54
      callback(mod);
55
    })(mod);
56
  }
57
};
58
59
// ------------------------------------------
60
//  CLASS: PLUGIN
61
// ------------------------------------------
62
63
var TYPE_MODULES  = 'modules';
64
var TYPE_PHANTOMS = 'phantoms';
65
var TYPE_CRON     = 'cron';
66
67
function Plugin(options) {
68
  extend(false, this, options);
69
  
70
  // Link configuration
71
  this.config   = Config[TYPE_MODULES][this.name];
0 ignored issues
show
Bug introduced by
The variable Config seems to be never declared. If this is a global, consider adding a /** global: Config */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
72
  this.phantoms = Config[TYPE_PHANTOMS][this.name];
73
  this.cron     = Config[TYPE_CRON][this.name];
74
  
75
  // Check has {plugin}.js
76
  var script = SARAH.ConfigManager.PLUGIN+'/'+this.name+'/'+this.name+'.js';
0 ignored issues
show
Bug introduced by
The variable SARAH seems to be never declared. If this is a global, consider adding a /** global: SARAH */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
77
  if (fs.existsSync(script)){ 
78
    this.script = script;
79
  }
80
  
81
  // Check has custom portlet.ejs
82
  var template = SARAH.ConfigManager.PLUGIN+'/'+this.name+'/portlet.ejs';
83
  if (fs.existsSync(template)){
84
    this.template = template;
85
  } else {
86
    this.template = 'portlet.html';
87
  }
88
  
89
  // Check has index.ejs
90
  var index = SARAH.ConfigManager.PLUGIN+'/'+this.name+'/index.ejs';
91
  if (fs.existsSync(index)){
92
    this.index = index;
93
  }
94
}
95
96
Plugin.prototype.isDisabled = function(){
97
  if (!this.script) return true;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
98
  return this.config.disabled;
99
}
100
101
102
Plugin.prototype.getLocale = function(locale){
103
  var path = SARAH.ConfigManager.PLUGIN+'/'+this.name+'/locales/'+locale+'.js';
0 ignored issues
show
Bug introduced by
The variable SARAH seems to be never declared. If this is a global, consider adding a /** global: SARAH */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
104
  if (!fs.existsSync(path)){ info('No locals',path); return; }
105
  try { 
106
    var json = fs.readFileSync(path,'utf-8');
107
    info('Loading locales %s', path); 
108
    if (json) return JSON.parse(json); 
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
109
  } 
110
  catch(ex){ warn("Can't parse %s locales in %s", this.name, locale); }
111
  
112
  return false;
113
}
114
115
Plugin.prototype.getInstance = function(uncache){
116
  try {
117
    // Dispose
118
    if (Config.debug || uncache){ 
0 ignored issues
show
Bug introduced by
The variable Config seems to be never declared. If this is a global, consider adding a /** global: Config */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
119
      if (this._script && this._script.dispose){ this._script.dispose(SARAH); }
0 ignored issues
show
Bug introduced by
The variable SARAH seems to be never declared. If this is a global, consider adding a /** global: SARAH */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
120
      require.uncache(this.script); 
121
    }
122
    
123
    // Require
124
    this._script = require(this.script);
125
    
126
    // Initialise
127
    if (!this._script.initialized){
128
      this._script.initialized = true;
129
      if (this._script.init){ this._script.init(SARAH); }
130
    }
131
    
132
    // Last Modified
133
    var modified = fs.statSync(this.script).mtime.getTime();
134
    if (!this._script.lastModified){
135
      this._script.lastModified = modified;
136
    }
137
    
138
    // Reload if new version
139
    if (this._script.lastModified < modified){
140
      info('Reloading: ', this.name);
141
      return this.getInstance(true);
142
    }
143
    
144
    return this._script;
145
  } 
146
  catch (ex) { 
147
    warn('Error while loading plugin: %s', this.name, ex.message, ex.stack);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
148
  }
149
}
150
151
// ------------------------------------------
152
//  CACHE PLUGINS
153
// ------------------------------------------
154
155
var cache    = {};
156
var getCache = function(){ return cache;  }
157
158
var refresh = function(){
159
  
160
  cache = {};
161
  
162
  // Find config
163
  var keys = Object.keys(Config[TYPE_MODULES]);
0 ignored issues
show
Bug introduced by
The variable Config seems to be never declared. If this is a global, consider adding a /** global: Config */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
164
  
165
  // Build a list of plugins
166
  for(var i = 0 ; i < keys.length ; i++){
167
    var key = keys[i];
168
    cache[key] = new Plugin ({'name' : key });
169
    cache[key].getInstance();
170
  }
171
  
172
  keys = Object.keys(Config[TYPE_PHANTOMS]);
173
  for(var i = 0 ; i < keys.length ; i++){
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable i already seems to be declared on line 166. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
174
    var key = keys[i];
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable key already seems to be declared on line 167. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
175
    if (cache[key]) continue;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
176
    cache[key] = new Plugin ({'name' : key });
177
    cache[key].getInstance();
178
  }
179
  
180
  keys = Object.keys(Config[TYPE_CRON]);
181
  for(var i = 0 ; i < keys.length ; i++){
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable i already seems to be declared on line 166. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
182
    var key = keys[i];
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable key already seems to be declared on line 167. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
183
    if (cache[key]) continue;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
184
    cache[key] = new Plugin ({'name' : key });
185
    cache[key].getInstance();
186
  }
187
}
188
189
// ------------------------------------------
190
//  PLUGIN LOCALES
191
// ------------------------------------------
192
193
var getLocales = function(locale){ 
194
  var prop   = {}
195
  var keys   = Object.keys(cache);
196
  for(var i  = 0 ; i < keys.length ; i++){
197
    var key  = keys[i];
198
    var json = cache[key].getLocale(locale);
199
    if (json){ extend(true, prop, json); }
200
  }
201
  return prop;  
202
}
203
204
// ------------------------------------------
205
//  PLUGIN LIST
206
// ------------------------------------------
207
208
var sort = function(ids, xPos, yPos){
209
  for(var i = 0 ; i < ids.length ; i++){
210
    var tmp = cache[ids[i]];
211
    if (tmp){
212
      var cfg = tmp.config;
213
      cfg.x = parseInt(xPos[i])+1;
214
      cfg.y = parseInt(yPos[i])+1;
215
    }
216
  }
217
  getList(true);
218
}
219
220
var getList = function(clean){ 
221
  
222
  if (clean){ refresh(); }
223
  
224
  var keys = Object.keys(cache);
225
  keys = keys.sort(function(k1, k2){
226
    var conf1 = cache[k1].config;
227
    var conf2 = cache[k2].config;
228
    
229
    if (!conf1.y) return  1;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
230
    if (!conf2.y) return -1;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
231
    
232
    if (conf1.y < conf2.y) return  -1;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
233
    if (conf1.y > conf2.y) return   1;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
234
    return conf1.x < conf2.x ? -1 : 1;
235
  });
236
  
237
  var list = [];
238
  for(var i = 0 ; i < keys.length ; i++){
239
    var key = keys[i];
240
    var plugin = cache[key];
241
    
242
    // Skip disabled plugin
243
    if (plugin.isDisabled()){ continue; }
244
    
245
    list.push(plugin);
246
  }
247
  return list;
248
}
249
250
251
// ------------------------------------------
252
//  FIND / SEEK
253
// ------------------------------------------
254
255
var find = function(name){
256
  return cache[name];
257
}
258
259
var exists = function(name){
260
  var plugin = find(name);
261
  return plugin ? true : false;
262
}
263
264
var remove = function(name, callback){
265
  var plugin = find(name);
266
  if (!plugin){ return callback(); }
267
  
268
  // Remove from filesystem
269
  var path = SARAH.ConfigManager.PLUGIN+'/'+name;
0 ignored issues
show
Bug introduced by
The variable SARAH seems to be never declared. If this is a global, consider adding a /** global: SARAH */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
270
  info('Removing %s plugin...', path);
271
  if (fs.existsSync(path)){ fs.removeSync(path); }
272
  
273
  // Remove in memory
274
  refresh();
275
  
276
  callback();
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
277
}
278
279
// ------------------------------------------
280
//  EVENT
281
// ------------------------------------------
282
283
var events = require('events');
284
var ee = new events.EventEmitter();
285
286
var listen = function(event, callback){
287
  ee.on(event, callback);
288
}
289
290
var trigger = function(event, data){
291
  ee.emit(event, data);
292
}
293
294
var socket = function(io){
295
  io.on('connection', function(socket){
296
    socket.on('disconnect', function(){ });
297
    
298
    for(var name in cache){
0 ignored issues
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
299
      plugin = cache[name].getInstance();
0 ignored issues
show
Bug introduced by
The variable plugin seems to be never declared. Assigning variables without defining them first makes them global. If this was intended, consider making it explicit like using window.plugin.
Loading history...
300
      if (plugin.socket) plugin.socket(io, socket);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
301
    }
302
  });
303
}
304
305
// ------------------------------------------
306
//  ROUTER
307
// ------------------------------------------
308
309
var Router = express.Router();
310
311
Router.get('/plugin/help/:name', function(req, res, next) { 
312
  var name   = req.params.name; 
313
  var plugin = find(name);
314
  
315
  if (plugin && plugin.index) {
316
    return res.render(plugin.index, {'title' : i18n('modal.plugin.help', name)});
317
  }
318
  next();
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
319
});
320
321
Router.get('/plugin/github/:name', function(req, res, next) { 
0 ignored issues
show
Unused Code introduced by
The parameter next is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
322
  var name   = req.params.name; 
323
  SARAH.Marketplace.getCommits(name, function(commits){
0 ignored issues
show
Bug introduced by
The variable SARAH seems to be never declared. If this is a global, consider adding a /** global: SARAH */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
324
    res.render('plugin/github.ejs', {
325
      'title'   : i18n('modal.plugin.github', name),
326
      'commits' : commits
327
    });
328
  });
329
});
330
331
Router.get('/plugin/config/:name', function(req, res, next) { 
0 ignored issues
show
Unused Code introduced by
The parameter next is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
332
  var name   = req.params.name; 
333
  return res.render('plugin/config.ejs', {'title' : i18n('modal.plugin.config', name) });
334
});
335
336
Router.post('/plugin/config/:name', function(req, res, next) { 
0 ignored issues
show
Unused Code introduced by
The parameter next is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
337
  var name    = req.params.name; 
338
  var plugin  = find(name);
0 ignored issues
show
Unused Code introduced by
The variable plugin seems to be never used. Consider removing it.
Loading history...
339
  var keys    = Object.keys(req.body);
340
  for(var i   = 0 ; i < keys.length ; i++){
341
    var key   = keys[i];
342
    var value = Helper.parse(req.body[key]);
0 ignored issues
show
Bug introduced by
The variable Helper seems to be never declared. If this is a global, consider adding a /** global: Helper */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
343
    var pfx   = key.substring(0, key.indexOf('.'));  
344
    var prop  = key.substring(key.indexOf('.')+1);
345
    
346
    // skip internal parameter like ajax 
347
    if (!pfx) continue;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
348
    
349
    info('[%s] %s.%s.%s = %s',key, pfx, name, prop, value);
350
    Config[pfx][name][prop] = value;
0 ignored issues
show
Bug introduced by
The variable Config seems to be never declared. If this is a global, consider adding a /** global: Config */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
351
  }
352
  SARAH.ConfigManager.save();
0 ignored issues
show
Bug introduced by
The variable SARAH seems to be never declared. If this is a global, consider adding a /** global: SARAH */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
353
354
  var referer = req.headers.referer;
355
  if (referer && referer.indexOf('/portal') < 0){
356
    return res.redirect(referer);
357
  } else {
358
    return res.render('plugin/config.ejs', {'title' : i18n('modal.plugin.config', name), 'message' : true });
359
  }
360
});
361
362
Router.get('/plugin/edit/:name', function(req, res, next) { 
0 ignored issues
show
Unused Code introduced by
The parameter next is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
363
  var name   = req.params.name; 
364
  var plugin = find(name);
0 ignored issues
show
Unused Code introduced by
The variable plugin seems to be never used. Consider removing it.
Loading history...
365
  return res.render('plugin/edit.ejs', {'title' : i18n('modal.plugin.edit', name)});
366
});
367
368
Router.all('/plugin/sort', function(req, res, next) { 
0 ignored issues
show
Unused Code introduced by
The parameter next is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
369
  sort(req.query.ids, req.query.xPos, req.query.yPos);
370
  SARAH.ConfigManager.save();
0 ignored issues
show
Bug introduced by
The variable SARAH seems to be never declared. If this is a global, consider adding a /** global: SARAH */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
371
  res.end();
372
});
373
374
Router.all('/plugin/:name/*', function(req, res, next) {
0 ignored issues
show
Unused Code introduced by
The parameter next is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
375
  var name   = req.params.name;
376
  var plugin = find(name);
377
  if (!plugin) return res.end();
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
378
  
379
  var path = req.params[0];
380
  if (!path) return res.end();
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
381
  
382
  try {
383
    var fullpath = SARAH.ConfigManager.PLUGIN+'/'+name+'/'+path;
0 ignored issues
show
Bug introduced by
The variable SARAH seems to be never declared. If this is a global, consider adding a /** global: SARAH */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
384
    if (fs.existsSync(fullpath)){ 
385
      res.render(fullpath, { "plugin" : plugin, "title" : (req.query.title || req.body.title || "") });
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
386
    } else {
387
      warn('path not found:', fullpath);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
388
    }
389
  } 
390
  catch (ex){ 
391
    warn('Error' , fullpath, ex.stack); 
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
392
  }
393
});
394
395
Router.all('/plugin/:name*', function(req, res, next) { 
0 ignored issues
show
Unused Code introduced by
The parameter next is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
396
  var plugin = find(req.params.name);
397
  if (!plugin) return res.end();
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
398
  
399
  var render = function(){
400
    res.render('portal/portlet.ejs', { "plugin" : plugin});
401
  }
402
  
403
  var instance = plugin.getInstance();
404
  if (instance.ajax){ instance.ajax(req, res, render); } else { render(); }
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
405
});
406
407
Router.all('/static/:name/*', function(req, res, next) { 
408
  var plugin = find(req.params.name);
409
  if (!plugin) return res.end();
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
410
  
411
  var instance = plugin.getInstance();
412
  if (instance.route) { 
413
    instance.route(req, res, next); 
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
414
  } else { next(); }
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
415
});
416
417
418
// ------------------------------------------
419
//  PUBLIC
420
// ------------------------------------------
421
422
var PluginManager = {
423
  'init' : init,
424
  'getCache'      : getCache,
425
  'getList'       : getList,
426
  'getLocales'    : getLocales,
427
  
428
  'find'          : find,
429
  'exists'        : exists,
430
  'remove'        : remove,
431
  
432
  'socket'        : socket,            
433
  'trigger'       : trigger,
434
  'listen'        : listen,
435
  
436
  'Router'        : Router
437
}
438
439
// Exports Manager
440
exports.init = PluginManager.init;