Skip to content
This repository was archived by the owner on Sep 16, 2025. It is now read-only.

Commit d4a991b

Browse files
refactor(slugService): move updateSlug check and get reference fields to separate files
1 parent 78ca3f6 commit d4a991b

File tree

4 files changed

+167
-85
lines changed

4 files changed

+167
-85
lines changed

server/services/slug-service.js

Lines changed: 0 additions & 85 deletions
This file was deleted.
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
'use strict';
2+
3+
const getReferenceFieldValues = (ctx, data, references) => {
4+
return references
5+
.filter((referenceField) => {
6+
// check action specific fields
7+
if (
8+
referenceField === 'id' &&
9+
(ctx.action === 'afterCreate' || ctx.action === 'beforeUpdate')
10+
) {
11+
return true;
12+
}
13+
14+
// check general data fields
15+
if (typeof data[referenceField] === 'undefined') {
16+
return false;
17+
}
18+
19+
if (data[referenceField] === null) {
20+
return false;
21+
}
22+
23+
if (typeof data[referenceField] === 'string' && data[referenceField].length === 0) {
24+
return false;
25+
}
26+
27+
return true;
28+
})
29+
.map((referenceField) => {
30+
if (referenceField === 'id') {
31+
return ctx.result ? ctx.result.id : ctx.params.where.id;
32+
}
33+
34+
return data[referenceField];
35+
});
36+
};
37+
38+
module.exports = {
39+
getReferenceFieldValues,
40+
};
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
'use strict';
2+
3+
const _ = require('lodash');
4+
const { toSlug } = require('../../utils/slugification');
5+
const { getPluginService } = require('../../utils/getPluginService');
6+
const { shouldUpdateSlug } = require('./shoudUpdateSlug');
7+
const { getReferenceFieldValues } = require('./getReferenceFieldValues');
8+
9+
module.exports = ({ strapi }) => ({
10+
async slugify(ctx) {
11+
const { params, model: entityModel } = ctx;
12+
const settings = getPluginService('settingsService').get();
13+
const { data } = params;
14+
15+
const model = settings.modelsByUID[entityModel.uid];
16+
if (!data) {
17+
return;
18+
}
19+
20+
const { field, references } = model;
21+
22+
// do not add/update slug if it already has a value unless settings specify otherwise
23+
if (!settings.shouldUpdateSlug && data[field]) {
24+
return;
25+
}
26+
27+
// ensure the reference field has data
28+
let referenceFieldValues = getReferenceFieldValues(ctx, data, references);
29+
30+
// respect skip undefined fields setting
31+
const hasUndefinedFields = referenceFieldValues.length < references.length;
32+
if ((!settings.skipUndefinedReferences && hasUndefinedFields) || !referenceFieldValues.length) {
33+
return;
34+
}
35+
36+
// check if the slug should be updated based on the action type
37+
let shouldUpdateSlugByAction = await shouldUpdateSlug(strapi, ctx, references);
38+
if (!shouldUpdateSlugByAction) {
39+
return;
40+
}
41+
42+
referenceFieldValues = referenceFieldValues.join(' ');
43+
const toSlugOptions = settings.slugifyOptions;
44+
if (settings.slugifyWithCount) {
45+
toSlugOptions.slugifyWithCount = settings.slugifyWithCount;
46+
}
47+
48+
// update slug field based on action type
49+
const slug = toSlug(referenceFieldValues, toSlugOptions);
50+
if (ctx.action === 'beforeCreate' || ctx.action === 'beforeUpdate') {
51+
data[field] = slug;
52+
} else if (ctx.action === 'afterCreate') {
53+
strapi.entityService.update(model.uid, ctx.result.id, {
54+
data: {
55+
slug,
56+
},
57+
});
58+
}
59+
},
60+
61+
async findOne(uid, query) {
62+
const slugs = await strapi.entityService.findMany(uid, query);
63+
64+
// single
65+
if (slugs && _.isPlainObject(slugs)) {
66+
return slugs;
67+
}
68+
69+
// collection
70+
if (slugs && _.isArray(slugs) && slugs.length) {
71+
return slugs[0];
72+
}
73+
74+
// no result
75+
return null;
76+
},
77+
});
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
'use strict';
2+
3+
const { getReferenceFieldValues } = require('./getReferenceFieldValues');
4+
5+
const shouldUpdateSlugInAfterCreate = (strapi, ctx, references) => {
6+
if (!references.includes('id')) {
7+
return false;
8+
}
9+
10+
return true;
11+
};
12+
13+
const shouldUpdateSlugInBeforeCreate = (strapi, ctx, references) => {
14+
if (references.includes('id')) {
15+
return false;
16+
}
17+
18+
return true;
19+
};
20+
21+
const shouldUpdateSlugInBeforeUpdate = async (strapi, ctx, references) => {
22+
const record = await strapi.entityService.findOne(ctx.model.uid, ctx.params.where.id);
23+
24+
let currentReferenceFieldValues = getReferenceFieldValues(ctx, record, references);
25+
let referenceFieldValues = getReferenceFieldValues(ctx, ctx.params.data, references);
26+
27+
// only update if reference a reference field has changed
28+
if (JSON.stringify(referenceFieldValues) == JSON.stringify(currentReferenceFieldValues)) {
29+
return false;
30+
}
31+
32+
return true;
33+
};
34+
35+
const shouldUpdateSlug = async (strapi, ctx, references) => {
36+
let shouldUpdate = false;
37+
if (ctx.action === 'beforeCreate') {
38+
shouldUpdate = shouldUpdateSlugInBeforeCreate(strapi, ctx, references);
39+
} else if (ctx.action === 'afterCreate') {
40+
shouldUpdate = shouldUpdateSlugInAfterCreate(strapi, ctx, references);
41+
} else if (ctx.action === 'beforeUpdate') {
42+
shouldUpdate = shouldUpdateSlugInBeforeUpdate(strapi, ctx, references);
43+
}
44+
45+
return shouldUpdate;
46+
};
47+
48+
module.exports = {
49+
shouldUpdateSlug,
50+
};

0 commit comments

Comments
 (0)