Ghost/core/server/services/url/UrlService.js
kirrg001 ab5199267b Renamed urlService.getUrl to urlService.getUrlByResourceId
no issue

- explicit function naming
- no functional change, only renaming
2018-04-25 19:37:39 +02:00

145 lines
4.3 KiB
JavaScript

'use strict';
const _debug = require('ghost-ignition').debug._base,
debug = _debug('ghost:services:url:service'),
_ = require('lodash'),
common = require('../../lib/common'),
UrlGenerator = require('./UrlGenerator'),
Queue = require('./Queue'),
Urls = require('./Urls'),
Resources = require('./Resources'),
localUtils = require('./utils');
class UrlService {
constructor(options) {
options = options || {};
this.utils = localUtils;
// You can disable the url preload, in case we encounter a problem with the new url service.
if (options.disableUrlPreload) {
return;
}
this.finished = false;
this.urlGenerators = [];
this.urls = new Urls();
this.queue = new Queue();
this.resources = new Resources(this.queue);
this._listeners();
}
_listeners() {
/**
* The purpose of this event is to notify the url service as soon as a channel get's created.
*/
this._onRoutingTypeListener = this._onRoutingType.bind(this);
common.events.on('routingType.created', this._onRoutingTypeListener);
/**
* The queue will notify us if url generation has started/finished.
*/
this._onQueueStartedListener = this._onQueueStarted.bind(this);
this.queue.addListener('started', this._onQueueStartedListener);
this._onQueueEndedListener = this._onQueueEnded.bind(this);
this.queue.addListener('ended', this._onQueueEnded.bind(this));
this._resetListener = this.reset.bind(this);
common.events.on('server.stop', this._resetListener);
}
_onQueueStarted(event) {
if (event === 'init') {
this.finished = false;
}
}
_onQueueEnded(event) {
if (event === 'init') {
this.finished = true;
}
}
_onRoutingType(routingType) {
debug('routingType.created');
let urlGenerator = new UrlGenerator(routingType, this.queue, this.resources, this.urls, this.urlGenerators.length);
this.urlGenerators.push(urlGenerator);
}
/**
* You have a url and want to know which the url belongs to.
* It's in theory possible that multiple resources generate the same url,
* but they both would serve different content e.g. static pages and collections.
*
* We only return the resource, which would be served.
*/
getResource(url) {
let objects = this.urls.getByUrl(url);
if (!objects.length) {
if (!this.hasFinished()) {
throw new common.errors.InternalServerError({
message: 'UrlService is processing.',
code: 'URLSERVICE_NOT_READY'
});
} else {
return null;
}
}
if (objects.length > 1) {
objects = _.reduce(objects, (toReturn, object) => {
if (!toReturn.length) {
toReturn.push(object);
} else {
const i1 = _.findIndex(this.urlGenerators, {uid: toReturn[0].generatorId});
const i2 = _.findIndex(this.urlGenerators, {uid: object.generatorId});
if (i2 < i1) {
toReturn = [];
toReturn.push(object);
}
}
}, []);
}
return objects[0].resource;
}
hasFinished() {
return this.finished;
}
/**
* Get url by resource id.
*/
getUrlByResourceId(id) {
const obj = this.urls.getByResourceId(id);
if (obj) {
return obj.url;
}
return null;
}
reset() {
this.urlGenerators = [];
this.urls.reset();
this.queue.reset();
this.resources.reset();
this._onQueueStartedListener && this.queue.removeListener('started', this._onQueueStartedListener);
this._onQueueEndedListener && this.queue.removeListener('ended', this._onQueueEndedListener);
this._onRoutingTypeListener && common.events.removeListener('routingType.created', this._onRoutingTypeListener);
this._resetListener && common.events.removeListener('server.stop', this._resetListener);
}
}
module.exports = UrlService;