unbuilt/admin/assets/js/hooks/controllers/args.js   F
last analyzed

Complexity

Total Complexity 75
Complexity/F 2.42

Size

Lines of Code 464
Function Count 31

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 0
nc 48
dl 0
loc 464
rs 3.8888
c 0
b 0
f 0
wmc 75
mnd 3
bc 74
fnc 31
bpm 2.387
cpm 2.4192
noi 25

20 Functions

Rating   Name   Duplication   Size   Complexity  
A Backbone.Model.extend.parseArgSlug 0 19 3
B Backbone.Model.extend.getEventArgs 0 25 3
A Backbone.Model.extend.getEventArg 0 14 4
B Backbone.Model.extend.getHierarchiesMatching 0 38 5
A Parent.extend.getChildren 0 3 1
B Backbone.Model.extend.getChildren 0 24 2
B Backbone.Model.extend.getChild 0 22 4
A Arg.extend.getChildren 0 1 1
A Backbone.Model.extend.defaults 0 3 1
A Parent.extend.getChild 0 3 1
A Backbone.Model.extend.isEventRepeatable 0 6 1
B Backbone.Model.extend.buildHierarchyHumanId 0 30 1
A Backbone.Model.extend.getEntity 0 16 3
B Backbone.Model.extend._hierarchyMatcher 0 50 4
A Arg.extend.getChild 0 1 1
A Backbone.Model.extend._getEntityData 0 13 2
A Arg.extend.initialize 0 3 1
C Backbone.Model.extend.getArgsFromHierarchy 0 33 7
A Parent.extend.parseArgSlug 0 11 2
B Backbone.Model.extend._getHierarchiesMatching 0 47 6

How to fix   Complexity   

Complexity

Complex classes like unbuilt/admin/assets/js/hooks/controllers/args.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
/**
2
 * wp.wordpoints.hooks.view.Args
3
 *
4
 * @class
5
 * @augments Backbone.View
6
 * @augments wp.wordpoints.hooks.view.Base
7
 */
8
var ArgsCollection = wp.wordpoints.hooks.model.Args,
0 ignored issues
show
Bug introduced by
The variable wp seems to be never declared. If this is a global, consider adding a /** global: wp */ 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...
9
	l10n = wp.wordpoints.hooks.view.l10n,
10
	Args;
11
12
Args = Backbone.Model.extend({
0 ignored issues
show
Bug introduced by
The variable Backbone seems to be never declared. If this is a global, consider adding a /** global: Backbone */ 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...
13
14
	defaults: {
15
		events: {},
16
		entities: {}
17
	},
18
19
	getEventArg: function ( eventSlug, slug ) {
20
21
		var event = this.get( 'events' )[ eventSlug ];
22
23
		if ( ! event || ! event.args || ! event.args[ slug ] ) {
24
			return false;
25
		}
26
27
		var entity = this.getEntity( slug );
28
29
		_.extend( entity.attributes, event.args[ slug ] );
0 ignored issues
show
Bug introduced by
The variable _ seems to be never declared. If this is a global, consider adding a /** global: _ */ 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...
30
31
		return entity;
32
	},
33
34
	getEventArgs: function ( eventSlug ) {
35
36
		var argsCollection = new ArgsCollection(),
37
			event = this.get( 'events' )[ eventSlug ];
38
39
		if ( typeof event === 'undefined' || typeof event.args === 'undefined' ) {
40
			return argsCollection;
41
		}
42
43
		_.each( event.args, function ( arg ) {
0 ignored issues
show
Bug introduced by
The variable _ seems to be never declared. If this is a global, consider adding a /** global: _ */ 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...
44
45
			var entity = this.getEntity( arg.slug );
46
47
			if ( ! entity ) {
48
				return;
49
			}
50
51
			_.extend( entity.attributes, arg );
0 ignored issues
show
Bug introduced by
The variable _ seems to be never declared. If this is a global, consider adding a /** global: _ */ 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...
52
53
			argsCollection.add( entity );
54
55
		}, this );
56
57
		return argsCollection;
58
	},
59
60
	isEventRepeatable: function ( slug ) {
61
62
		var args = this.getEventArgs( slug );
63
64
		return _.isEmpty( args.where( { is_stateful: false } ) );
0 ignored issues
show
Bug introduced by
The variable _ seems to be never declared. If this is a global, consider adding a /** global: _ */ 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...
65
	},
66
67
	parseArgSlug: function ( slug ) {
68
69
		var isArray = false,
70
			isAlias = false;
71
72
		if ( '{}' === slug.slice( -2 ) ) {
73
			isArray = true;
74
			slug = slug.slice( 0, -2 );
75
		}
76
77
		var parts = slug.split( ':', 2 );
78
79
		if ( parts[1] ) {
80
			isAlias = parts[0];
81
			slug = parts[1];
82
		}
83
84
		return { slug: slug, isArray: isArray, isAlias: isAlias };
85
	},
86
87
	_getEntityData: function ( slug ) {
88
89
		var parsed = this.parseArgSlug( slug ),
90
			entity = this.get( 'entities' )[ parsed.slug ];
91
92
		if ( ! entity ) {
93
			return false;
94
		}
95
96
		entity = _.extend( {}, entity, { slug: slug, _canonical: parsed.slug } );
0 ignored issues
show
Bug introduced by
The variable _ seems to be never declared. If this is a global, consider adding a /** global: _ */ 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...
97
98
		return entity;
99
	},
100
101
	getEntity: function ( slug ) {
102
103
		if ( slug instanceof Entity ) {
104
			return slug;
105
		}
106
107
		var entity = this._getEntityData( slug );
108
109
		if ( ! entity ) {
110
			return false;
111
		}
112
113
		entity = new Entity( entity );
114
115
		return entity;
116
	},
117
118
	getChildren: function ( slug ) {
119
120
		var entity = this._getEntityData( slug );
121
122
		if ( ! entity ) {
123
			return false;
124
		}
125
126
		var children = new ArgsCollection();
127
128
		_.each( entity.children, function ( child ) {
0 ignored issues
show
Bug introduced by
The variable _ seems to be never declared. If this is a global, consider adding a /** global: _ */ 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...
129
130
			var argType = Args.type[ child._type ];
131
132
			if ( ! argType ) {
133
				return;
134
			}
135
136
			children.add( new argType( child ) );
0 ignored issues
show
Coding Style Best Practice introduced by
By convention, constructors like argType should be capitalized.
Loading history...
137
138
		}, this );
139
140
		return children;
141
	},
142
143
	getChild: function ( entitySlug, childSlug ) {
144
145
		var entity = this._getEntityData( entitySlug );
146
147
		if ( ! entity ) {
148
			return false;
149
		}
150
151
		var child = entity.children[ childSlug ];
152
153
		if ( ! child ) {
154
			return false;
155
		}
156
157
		var argType = Args.type[ child._type ];
158
159
		if ( ! argType ) {
160
			return;
161
		}
162
163
		return new argType( child );
0 ignored issues
show
Coding Style Best Practice introduced by
By convention, constructors like argType should be capitalized.
Loading history...
164
	},
165
166
	/**
167
	 *
168
	 * @param hierarchy
169
	 * @param eventSlug Optional event for context.
170
	 * @returns {*}
171
	 */
172
	getArgsFromHierarchy: function ( hierarchy, eventSlug ) {
173
174
		var args = [], parent, arg, slug;
175
176
		for ( var i = 0; i < hierarchy.length; i++ ) {
177
178
			slug = hierarchy[ i ];
179
180
			if ( parent ) {
181
				if ( ! parent.getChild ) {
182
					return false;
183
				}
184
185
				arg = parent.getChild( slug );
186
			} else {
187
				if ( eventSlug && this.parseArgSlug( slug ).isAlias ) {
188
					arg = this.getEventArg( eventSlug, slug );
189
				} else {
190
					arg = this.getEntity( slug );
191
				}
192
			}
193
194
			if ( ! arg ) {
195
				return false;
196
			}
197
198
			parent = arg;
199
200
			args.push( arg );
201
		}
202
203
		return args;
204
	},
205
206
	getHierarchiesMatching: function ( options ) {
207
208
		var args = [], hierarchies = [], hierarchy = [];
0 ignored issues
show
Unused Code introduced by
The assignment to variable args seems to be never used. Consider removing it.
Loading history...
209
210
		options = _.extend( {}, options );
0 ignored issues
show
Bug introduced by
The variable _ seems to be never declared. If this is a global, consider adding a /** global: _ */ 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...
211
212
		if ( options.event ) {
213
			options.top = this.getEventArgs( options.event ).models;
214
		}
215
216
		if ( options.top ) {
217
			args = _.isArray( options.top ) ? options.top : [ options.top ];
218
		} else {
219
			args = _.keys( this.get( 'entities' ) );
220
		}
221
222
		var matcher = this._hierarchyMatcher( options, hierarchy, hierarchies );
223
224
		if ( ! matcher ) {
225
			return hierarchies;
226
		}
227
228
		_.each( args, function ( slug ) {
229
230
			var arg = this.getEntity( slug );
231
232
			this._getHierarchiesMatching(
233
				arg
234
				, hierarchy
235
				, hierarchies
236
				, matcher
237
			);
238
239
240
		}, this );
241
242
		return hierarchies;
243
	},
244
245
	_hierarchyMatcher: function ( options, hierarchy, hierarchies ) {
246
247
		var filters = [], i;
248
249
		if ( options.end ) {
250
			filters.push( {
251
				method: _.isFunction( options.end ) ? 'filter' : 'where',
0 ignored issues
show
Bug introduced by
The variable _ seems to be never declared. If this is a global, consider adding a /** global: _ */ 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...
252
				arg: options.end
253
			});
254
		}
255
256
		if ( ! filters ) {
257
			return false;
258
		}
259
260
		return function ( subArgs, hierachy ) {
261
262
			var matching = [], matches;
263
264
			if ( subArgs instanceof Backbone.Collection ) {
0 ignored issues
show
Bug introduced by
The variable Backbone seems to be never declared. If this is a global, consider adding a /** global: Backbone */ 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...
265
				subArgs = subArgs.models;
266
			} else {
267
				subArgs = _.clone( subArgs );
0 ignored issues
show
Bug introduced by
The variable _ seems to be never declared. If this is a global, consider adding a /** global: _ */ 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...
268
			}
269
270
			_.each( subArgs, function ( match ) {
271
				match.hierachy = hierachy;
272
				matching.push( match );
273
			});
274
275
			matching = new ArgsCollection( matching );
276
277
			for ( i = 0; i < filters.length; i++ ) {
0 ignored issues
show
Bug introduced by
The variable i is changed as part of the for loop for example by i++ on line 277. Only the value of the last iteration will be visible in this function if it is called after the loop.
Loading history...
278
279
				matches = matching[ filters[ i ].method ]( filters[ i ].arg );
280
281
				if ( _.isEmpty( matches ) ) {
0 ignored issues
show
Bug introduced by
The variable _ seems to be never declared. If this is a global, consider adding a /** global: _ */ 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...
282
					return;
283
				}
284
285
				matching.reset( matches );
286
			}
287
288
			matching.each( function ( match ) {
289
				hierarchy.push( match );
290
				hierarchies.push( _.clone( hierarchy ) );
0 ignored issues
show
Bug introduced by
The variable _ seems to be never declared. If this is a global, consider adding a /** global: _ */ 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...
291
				hierarchy.pop();
292
			});
293
		};
294
	},
295
296
	_getHierarchiesMatching: function ( arg, hierarchy, hierarchies, addMatching ) {
297
298
		var subArgs;
299
300
		// Check the top-level args as well.
301
		if ( hierarchy.length === 0 ) {
302
			addMatching( [ arg ], hierarchy );
303
		}
304
305
		if ( arg instanceof Parent ) {
306
			subArgs = arg.getChildren();
307
		}
308
309
		if ( ! subArgs ) {
310
			return;
311
		}
312
313
		// If this is an entity, check if that entity is already in the
314
		// hierarchy, and don't add it again, to prevent infinite loops.
315
		if ( hierarchy.length % 2 === 0 ) {
316
			var loops = _.filter( hierarchy, function ( item ) {
0 ignored issues
show
Bug introduced by
The variable _ seems to be never declared. If this is a global, consider adding a /** global: _ */ 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...
317
				return item.get( 'slug' ) === arg.get( 'slug' );
318
			});
319
320
			// We allow it to loop twice, but not to add the entity a third time.
321
			if ( loops.length > 1 ) {
322
				return;
323
			}
324
		}
325
326
		hierarchy.push( arg );
327
328
		addMatching( subArgs, hierarchy );
329
330
		subArgs.each( function ( subArg ) {
331
332
			this._getHierarchiesMatching(
333
				subArg
334
				, hierarchy
335
				, hierarchies
336
				, addMatching
337
			);
338
339
		}, this );
340
341
		hierarchy.pop();
342
	},
343
344
	buildHierarchyHumanId: function ( hierarchy ) {
345
346
		var humanId = '';
347
348
		_.each( hierarchy, function ( arg) {
0 ignored issues
show
Bug introduced by
The variable _ seems to be never declared. If this is a global, consider adding a /** global: _ */ 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...
349
350
			if ( ! arg ) {
351
				return;
352
			}
353
354
			var title = arg.get( 'title' );
355
356
			if ( ! title ) {
357
				return;
358
			}
359
360
			if ( '' !== humanId ) {
361
				// We compress relationships.
362
				if ( arg instanceof Entity ) {
363
					return;
364
				}
365
366
				humanId += l10n.separator;
367
			}
368
369
			humanId += title;
370
		});
371
372
		return humanId;
373
	}
374
375
}, { type: {} });
376
377
var Arg = Backbone.Model.extend({
0 ignored issues
show
Bug introduced by
The variable Backbone seems to be never declared. If this is a global, consider adding a /** global: Backbone */ 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...
378
379
	type: 'arg',
380
381
	idAttribute: 'slug',
382
383
	defaults: function () {
384
		return { _type: this.type };
385
	}
386
});
387
388
var Parent = Arg.extend({
389
390
	/**
391
	 * @abstract
392
	 *
393
	 * @param {string} slug The child slug.
0 ignored issues
show
Documentation introduced by
The parameter slug does not exist. Did you maybe forget to remove this comment?
Loading history...
394
	 */
395
	getChild: function () {},
396
397
	/**
398
	 * @abstract
399
	 */
400
	getChildren: function () {}
401
});
402
403
var Entity = Parent.extend({
404
	type: 'entity',
405
406
	getChild: function ( slug ) {
407
		return wp.wordpoints.hooks.Args.getChild( this.get( 'slug' ), slug );
0 ignored issues
show
Bug introduced by
The variable wp seems to be never declared. If this is a global, consider adding a /** global: wp */ 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...
408
	},
409
410
	getChildren: function () {
411
		return wp.wordpoints.hooks.Args.getChildren( this.get( 'slug' ) );
0 ignored issues
show
Bug introduced by
The variable wp seems to be never declared. If this is a global, consider adding a /** global: wp */ 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...
412
	}
413
});
414
415
var Relationship = Parent.extend({
416
	type: 'relationship',
417
418
	parseArgSlug: function ( slug ) {
419
420
		var isArray = false;
421
422
		if ( '{}' === slug.slice( -2 ) ) {
423
			isArray = true;
424
			slug = slug.slice( 0, -2 );
425
		}
426
427
		return { isArray: isArray, slug: slug };
428
	},
429
430
	getChild: function ( slug ) {
431
432
		var child;
433
434
		if ( slug !== this.get( 'secondary' ) ) {
435
			return false;
436
		}
437
438
		var parsed = this.parseArgSlug( slug );
439
440
		if ( parsed.isArray ) {
441
			child = new EntityArray({ entity_slug: parsed.slug });
442
		} else {
443
			child = wp.wordpoints.hooks.Args.getEntity( parsed.slug );
0 ignored issues
show
Bug introduced by
The variable wp seems to be never declared. If this is a global, consider adding a /** global: wp */ 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...
444
		}
445
446
		return child;
447
	},
448
449
	getChildren: function () {
450
		return new ArgsCollection( [ this.getChild( this.get( 'secondary' ) ) ] );
451
	}
452
});
453
454
var EntityArray = Arg.extend( {
455
	type: 'array',
456
457
	initialize: function () {
458
		this.set( 'slug', this.get( 'entity_slug' ) + '{}' );
459
	}
460
});
461
462
var Attr = Arg.extend( {
463
	type: 'attr'
464
});
465
466
Args.type.entity = Entity;
467
Args.type.relationship = Relationship;
468
Args.type.array = EntityArray;
469
Args.type.attr = Attr;
470
471
module.exports = Args;
472