UNPKG

@rnaga/wp-node

Version:

👉 **[View Full Documentation at rnaga.github.io/wp-node →](https://rnaga.github.io/wp-node/)**

907 lines (906 loc) • 36.6 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.PostTrx = void 0; const zod_1 = require("zod"); const common_1 = require("../common"); const config_1 = require("../config"); const components_1 = require("../core/components"); const current_1 = require("../core/current"); const options_1 = require("../core/options"); const comment_util_1 = require("../core/utils/comment.util"); const date_time_util_1 = require("../core/utils/date-time.util"); const link_util_1 = require("../core/utils/link.util"); const post_util_1 = require("../core/utils/post.util"); const query_util_1 = require("../core/utils/query.util"); const taxonomy_util_1 = require("../core/utils/taxonomy.util"); const validator_1 = require("../core/validator"); const database_1 = __importDefault(require("../database")); const component_1 = require("../decorators/component"); const val = __importStar(require("../validators")); const comment_trx_1 = require("./comment.trx"); const meta_trx_1 = require("./meta.trx"); const options_trx_1 = require("./options.trx"); const revision_trx_1 = require("./revision.trx"); const term_trx_1 = require("./term.trx"); const trx_1 = require("./trx"); const logger_1 = require("../core/logger"); let PostTrx = class PostTrx extends trx_1.Trx { database; logger; components; config; postUtil; taxonomyUtil; commentUtil; constructor(database, logger, components, config, postUtil, taxonomyUtil, commentUtil // private validator: Validator ) { super(components); this.database = database; this.logger = logger; this.components = components; this.config = config; this.postUtil = postUtil; this.taxonomyUtil = taxonomyUtil; this.commentUtil = commentUtil; } // update_posts_count async updateCount() { const queryUtil = this.components.get(query_util_1.QueryUtil); const counts = await queryUtil.posts((query) => { query.countPublished(); }, val.query.resultCount); //z.array(z.object({ count: z.number() }))); const count = counts?.count ?? 0; const optionsTrx = this.components.get(options_trx_1.OptionsTrx); await optionsTrx.insert("post_count", `${count}`); } // part of remove_user_from_blog async changeAuthor(fromUserId, toUserId) { const trx = await this.database.transaction; try { await trx .table(this.tables.get("posts")) .where("post_author", fromUserId) .update({ post_author: toUserId, }); } catch (e) { await trx.rollback(); throw new Error(`Failed to change author from: ${fromUserId} to: ${toUserId} - ${e}`); } await trx.commit(); return true; } // wp_insert_post async upsert(input) { const current = this.components.get(current_1.Current); const options = this.components.get(options_1.Options); const dateTimeUtil = this.components.get(date_time_util_1.DateTimeUtil); let update = false; let previousStatus = "new"; let postBefore = undefined; let desiredPostSlug = undefined; // Update if (input.ID && 0 < input.ID) { update = true; postBefore = await this.postUtil.get(input.ID); if (!postBefore.props) { throw new Error(`Post not found - ${input.ID}`); } input.guid = postBefore.props.guid; previousStatus = postBefore.props.post_status; desiredPostSlug = await postBefore.meta.get("_wp_desired_post_slug"); // Combine input with existing record input = { ...postBefore.props, post_categeory: ((await postBefore.terms("category")) ?? []).map((v) => v.term_id), tags_input: ((await postBefore.terms("post_tag")) ?? []).map((v) => v.term_id), ...input, }; } const parsedInput = val.trx.postUpsert.parse(input); const postDate = dateTimeUtil.get(input.post_date); const data = { ID: parsedInput.ID ?? 0, context: parsedInput.context, file: parsedInput.file, guid: parsedInput.guid, post_date: postDate.mySQLDatetime, post_date_gmt: postDate.mySQLGMTDatetime, meta_input: parsedInput.meta_input, post_status: parsedInput.post_status ?? "draft", post_type: parsedInput.post_type ?? "post", post_title: parsedInput.post_title, post_content: parsedInput.post_content, post_excerpt: parsedInput.post_excerpt, post_name: parsedInput.post_name, post_parent: parsedInput.post_parent, pinged: parsedInput.pinged, import_id: parsedInput.import_id, post_content_filtered: parsedInput.post_content_filtered, tags_input: parsedInput.tags_input, tax_input: parsedInput.tax_input, }; data.post_name = parsedInput.post_name ?? (update && postBefore && postBefore.props ? postBefore.props.post_name : ""); const postTypeObject = this.postUtil.getTypeObject(data.post_type); // Check empry fields if (["editor", "title", "excerpt"].every((v) => postTypeObject?.supports.includes(v)) && !parsedInput.post_content && !parsedInput.post_title && !parsedInput.post_excerpt) { throw new Error("Content, title, and excerpt are empty."); } if (data.post_type == "attachment" && !["inherit", "private", "trash", "auto-draft"].includes(data.post_status)) { data.post_status = "inherit"; } let postCategory = []; if (Array.isArray(parsedInput.post_categeory)) { postCategory = parsedInput.post_categeory.filter((v) => v > 0); } else if (update && !parsedInput.post_categeory) { postCategory = !postBefore ? [] : (await postBefore.terms("category"))?.map((term) => term.term_id) ?? []; } // Make sure we set a valid category. if (0 >= postCategory.length && "post" === data.post_type && "auto-draft" !== data.post_status) { const defaultCategory = (await options.get("default_category")) ?? []; if (!Array.isArray(defaultCategory)) { postCategory = [defaultCategory]; } } data.post_categeory = postCategory; /* * Don't allow contributors to set the post slug for pending review posts. * * For new posts check the primitive capability, for updates check the meta capability. */ if ("pending" === data.post_status && ((!update && postTypeObject?.capabilities && !(await current.user?.can(postTypeObject.capabilities["publish_posts"]))) || (update && !(await current.user?.can("publish_post", data.ID))))) { data.post_name = ""; } const validator = this.components.get(validator_1.Validator); /* * Create a valid post name. Drafts and pending posts are allowed to have * an empty post name. */ if (0 >= data.post_name.length) { if (!["draft", "pending", "auto-draft"].includes(data.post_status)) { data.post_name = validator.fieldSafe("posts", "post_title", data.post_title) ?? ""; } else { data.post_name = ""; } } else { // New post, or slug has changed. data.post_name = validator.fieldSafe("posts", "post_title", data.post_name) ?? ""; } data.post_modified = data.post_date; data.post_modified_gmt = data.post_date_gmt; if (update) { const currentDateTime = dateTimeUtil.get(); data.post_modified = currentDateTime.mySQLDatetime; data.post_modified_gmt = currentDateTime.mySQLGMTDatetime; } if ("attachment" !== data.post_type) { const postDate = dateTimeUtil.get(data.post_date_gmt); if ("publish" === data.post_status && postDate.isFuture()) { data.post_status = "future"; } else if ("future" === data.post_status && !postDate.isFuture()) { data.post_status = "publish"; } } // Comment status. data.comment_status = parsedInput.comment_status ? parsedInput.comment_status : update ? "closed" : await this.commentUtil.getDefaultStatus(data.post_type); // These variables are needed by compact() later. data.post_author = parsedInput.post_author > 0 ? parsedInput.post_author : current.user?.props?.ID ?? -1; data.ping_status = parsedInput.ping_status ?? this.commentUtil.getDefaultStatus(data.post_type, "pingback"); data.to_ping = data.to_ping ? validator.fieldSafe("posts", "to_ping", parsedInput.to_ping) : ""; /* * The 'wp_insert_post_parent' filter expects all variables to be present. * Previously, these variables would have already been extracted */ data.menu_order = parsedInput.menu_order ?? 0; data.post_password = parsedInput.post_password ?? ""; if ("private" === data.post_status) { data.post_password = ""; } const postNameTrashedSuffix = this.config.config.constants.TRASHED_SUFFIX_TO_POST_NAME_FOR_POST; /* * If the post is being untrashed and it has a desired slug stored in post meta, * reassign it. */ if ("trash" === previousStatus && "trash" !== data.post_status) { data.post_name = data.post_name.endsWith(postNameTrashedSuffix) ? data.post_name.replace(postNameTrashedSuffix, "") : data.post_name; if (desiredPostSlug) { data.post_name = desiredPostSlug; const metaTrx = this.components.get(meta_trx_1.MetaTrx); await metaTrx.remove("post", { objectId: data.ID, key: "_wp_desired_post_slug", }); } } // When trashing an existing post, change its slug to allow non-trashed posts to use it. if ("trash" === data.post_status && "trash" !== previousStatus && "new" !== previousStatus && postBefore?.props?.post_name && !postBefore.props.post_name.endsWith(postNameTrashedSuffix)) { const metaTrx = this.components.get(meta_trx_1.MetaTrx); await metaTrx.upsert("post", data.ID, "_wp_desired_post_slug", data.post_name); data.post_name = `${postBefore.props.post_name}${postNameTrashedSuffix}`; } data.post_name = await this.postUtil.getUniqueSlug(data.post_name, data.ID); // Don't unslash. data.post_mime_type = parsedInput.post_mime_type ?? ""; let dataUpsert = {}; try { dataUpsert = validator.execAny(update ? val.trx.postUpdate : val.trx.postInsert, Object.entries(data) .map(([key, value]) => ({ [key]: common_1.formatting.unslash(value), })) .reduce((obj, item) => ({ ...obj, ...item }), {})); } catch (e) { this.logger.warn(`parse error: ${e}`, { data }); throw e; } if (!dataUpsert) { throw new Error(`Invalid post data - ${JSON.stringify(data)}`); } dataUpsert.post_date = data.post_date; dataUpsert.post_date_gmt = data.post_date_gmt; let trx = await this.database.transaction; try { if (update) { await trx .table(this.tables.get("posts")) .where("ID", data.ID) .update(dataUpsert); } else { await trx .insert(dataUpsert) .into(this.tables.get("posts")) .then((v) => { data.ID = v[0]; }); } } catch (e) { await trx.rollback(); throw new Error(`Failed to insert post - ${e}`); } await trx.commit(); const post = await this.postUtil.get(data.ID); if (!post.props) { throw new Error(`Post Not Found - ${data.ID}`); } const postId = post.props.ID; // Set slug with title if (0 >= data.post_name.length && !["draft", "pending", "auto-draft"].includes(data.post_status)) { data.post_name = await this.postUtil.getUniqueSlug(common_1.formatting.slug(data.post_title), post); trx = await this.database.transaction; try { await trx.table(this.tables.get("posts")).where("ID", postId).update({ post_name: data.post_name, }); } catch (e) { await trx.rollback(); throw new Error(`Failed to update slug - ${e}`); } await trx.commit(); } // Sync categories const taxonomyCategory = await this.taxonomyUtil.get("category"); if (!taxonomyCategory.isDefault && taxonomyCategory.props?.objectType == data.post_type) { await this.syncCategories(post.props.ID, data.post_categeory); } // Sync tags const taxonomyPostTag = await this.taxonomyUtil.get("post_tag"); if (data.tags_input && !taxonomyPostTag.isDefault && taxonomyPostTag.props?.objectType == data.post_type) { await this.syncTerms(postId, data.tags_input); } let taxonomyInput = data.tax_input; // Add default term for all associated custom taxonomies. if ("auto-draft" !== data.post_status) { for (const taxonomy of await this.taxonomyUtil.getList({ objectType: post.props.post_type, })) { if (!taxonomy.props?.default_term) { continue; } // Filter out empty terms. if (taxonomyInput && taxonomyInput[taxonomy.name]) { taxonomyInput[taxonomy.name] = taxonomyInput[taxonomy.name].filter((v) => typeof v == "number" || v.length > 0); } // Passed custom taxonomy list overwrites the existing list if not empty. const terms = ((await this.components.get(query_util_1.QueryUtil).terms((query) => { query.withObjectIds([postId]).where("taxonomy", taxonomy.name); })) ?? []).map((v) => v.term_id); if (terms.length > 0 && (!taxonomyInput || !taxonomyInput[taxonomy.name])) { taxonomyInput = { ...taxonomyInput, [taxonomy.name]: terms }; } // Set default term id if (taxonomy.props.default_term && (!taxonomyInput || !taxonomyInput[taxonomy.name])) { taxonomyInput = { ...taxonomyInput, [taxonomy.name]: [taxonomy.props.default_term], }; } } } for (const [taxonomyName, tags] of Object.entries(taxonomyInput ?? {})) { const taxonomy = await this.taxonomyUtil.get(taxonomyName); if (taxonomy.isDefault) { continue; } if (taxonomy.props?.capabilities?.["assign_terms"] && (await current.user?.can(taxonomy.props?.capabilities["assign_terms"]))) { await this.syncTerms(postId, tags, taxonomy.name); } } const metaTrx = this.components.get(meta_trx_1.MetaTrx); const metaInput = data.meta_input; if (metaInput) { for (const [key, value] of Object.entries(metaInput)) { await metaTrx.upsert("post", postId, key, value, { serialize: typeof value == "object" || Array.isArray(value), }); } } // Set GUID. if (0 >= post.props.guid.length) { const linkUtil = this.components.get(link_util_1.LinkUtil); trx = await this.database.transaction; try { await trx .table(this.tables.get("posts")) .where("ID", postId) .update({ guid: await linkUtil.getPermalink(post), }); } catch (e) { await trx.rollback(); throw new Error(`Failed to udpate guid - ${e}`); } await trx.commit(); } if ("attachment" === data.post_type) { if (0 < data.file.length) { await this.syncAttachedFile(postId, data.file); } if (0 < data.context.length) { await metaTrx.upsert("post", postId, "_wp_attachment_context", data.context); } } return postId; } // wp_delete_post async remove(postId, force = false) { const EMPTY_TRASH_DAYS = this.config.config.constants.EMPTY_TRASH_DAYS; const queryUtil = this.components.get(query_util_1.QueryUtil); const posts = await queryUtil.posts((query) => { query.where("ID", postId); }); if (!posts) { return false; } const post = await this.postUtil.get(postId); if (!post.props) { return false; } const postType = post.props.post_type; if (!force && ("post" === postType || "page" === postType) && "trash" === (await this.postUtil.getStatus(post)) && EMPTY_TRASH_DAYS > 0) { return await this.trash(postId); } if ("attachment" === postType) { return await this.removeAttachment(postId, force); } const metaTrx = this.components.get(meta_trx_1.MetaTrx); await metaTrx.remove("post", { objectId: postId, key: "_wp_trash_meta_status", }); await metaTrx.remove("post", { objectId: postId, key: "_wp_trash_meta_time", }); const taxonomyUtil = this.components.get(taxonomy_util_1.TaxonomyUtil); const taxonomies = await taxonomyUtil.getList({ objectType: postType, }); const termTrx = this.components.get(term_trx_1.TermTrx); await termTrx.removeObjectTermRelationships(postId, taxonomies.map((taxonomy) => taxonomy.name)); const postTypeObject = this.postUtil.getTypeObject(postType); if (postTypeObject?.hierarchical) { // Point children of this page to its parent, also clean the cache of affected children. const children = await queryUtil.posts((query) => { query.where("ID", postId).where("post_type", postType); }); if (children) { const trx = await this.database.transaction; try { await trx .table(this.tables.get("posts")) .where("post_parent", postId) .where("post_type", postType) .update({ post_parent: post.props.post_parent, }); } catch (e) { await trx.rollback(); throw new Error(`Failed to update post - ${e}`); } await trx.commit(); } } const revisionsIds = ((await queryUtil.posts((query) => { query.where("post_parent", postId).where("post_type", "revision"); })) ?? []).map((post) => post.ID); const revisionTrx = this.components.get(revision_trx_1.RevisionTrx); for (const revisionId of revisionsIds) { await revisionTrx.remove(revisionId); } // Point all attachments to this post up one level. let trx = await this.database.transaction; try { await trx .table(this.tables.get("posts")) .where("post_parent", postId) .where("post_type", "attachment") .update({ post_parent: post.props.post_parent, }); } catch (e) { await trx.rollback(); throw new Error(`Failed to update attachment - ${e} `); } await trx.commit(); const commentIds = ((await queryUtil.comments((query) => { const { column } = query.alias; query .where("post_ID", postId) .builder.orderBy(column("comments", "comment_ID"), "desc"); })) ?? []).map((comment) => comment.comment_ID); const commentTrx = this.components.get(comment_trx_1.CommentTrx); for (const commentId of commentIds) { await commentTrx.remove(commentId, true); } await metaTrx.removeObject("post", postId); trx = await this.database.transaction; try { await trx.table(this.tables.get("posts")).where("ID", postId).del(); } catch (e) { await trx.rollback(); throw new Error(`Failed to delete post - ${e}`); } await trx.commit(); return post; } // wp_insert_attachment async insertAttachment(input, args) { const { file, parentPostId } = args ?? {}; input = { ...input, file: file ?? input.file, post_parent: parentPostId ?? input.post_parent, post_type: "attachment", }; return this.upsert(input); } // wp_update_attachment_metadata async syncAttachmentMetadata(postId, args) { const { data, remove = false } = args; const metaTrx = this.components.get(meta_trx_1.MetaTrx); const key = "_wp_attachment_metadata"; if (true !== remove) { await metaTrx.upsert("post", postId, key, data, { serialize: true, }); } else { await metaTrx.remove("post", { objectId: postId, key, }); } } // wp_delete_attachment async removeAttachment(postId, force = false) { const EMPTY_TRASH_DAYS = this.config.config.constants.EMPTY_TRASH_DAYS; const MEDIA_TRASH = this.config.config.constants.MEDIA_TRASH; const post = await this.postUtil.get(postId); if (!post.props || "attachment" == post.props.post_status) { return false; } if (!force && EMPTY_TRASH_DAYS > 0 && MEDIA_TRASH && "trash" !== post.props.post_status) { return await this.trash(postId); } const metaTrx = this.components.get(meta_trx_1.MetaTrx); await metaTrx.remove("post", { objectId: postId, key: "_wp_trash_meta_status", }); await metaTrx.remove("post", { objectId: postId, key: "_wp_trash_meta_time", }); const queryUtil = this.components.get(query_util_1.QueryUtil); // const attachmentMeta = await queryUtil.meta( // "post", // (query) => { // query // .withIds([postId]) // .withKeys(["_wp_attachment_metadata"]) // .builder.first(); // }, // val.database.wpPostMeta // ); // const backupSize = await queryUtil.meta( // "post", // (query) => { // query // .withIds([postId]) // .withKeys(["_wp_attachment_backup_sizes"]) // .builder.first(); // }, // val.database.wpPostMeta // ); // const file = await this.postUtil.getAttachedFile(postId); // wp_delete_object_term_relationships const termTrx = this.components.get(term_trx_1.TermTrx); await termTrx.removeObjectTermRelationships(postId, [ "category", "post_tag", ]); //await termTrx.syncObject(postId, [], "category"); //await termTrx.syncObject(postId, [], "post_tag"); const taxonomyUtil = this.components.get(taxonomy_util_1.TaxonomyUtil); const taxonomies = await taxonomyUtil.getList({ objectType: post.props.post_type, }); for (const taxonomy of taxonomies) { if (!["category", "post_tag"].includes(taxonomy.name)) { await termTrx.removeObjectTermRelationships(postId, [taxonomy.name]); ///await termTrx.syncObject(postId, [], taxonomy.name); } } // Delete all for any posts. await metaTrx.remove("post", { key: "_thumbnail_id", value: `${postId}`, deleteAll: true, }); const comments = (await queryUtil.comments((query) => { const { column } = query.alias; query .where("post_ID", postId) .builder.orderBy(column("comments", "comment_ID"), "desc"); })) ?? []; const commentTrx = this.components.get(comment_trx_1.CommentTrx); for (const comment of comments) { await commentTrx.remove(comment.comment_ID, true); } await metaTrx.removeObject("post", postId); const trx = await this.database.transaction; try { await trx.table(this.tables.get("posts")).where("ID", postId).del(); } catch (e) { await trx.rollback(); throw new Error(`Failed to delete post - ${e}`); } await trx.commit(); // wp_delete_attachment_files return post; } // wp_untrash_post async untrash(postId) { const post = await this.postUtil.get(postId); if (!post.props || "trash" !== post.props.post_status) { return false; } const previousStatus = await post.meta.get("_wp_trash_meta_status"); const newStatus = "attachment" === post.props.post_type ? "inherit" : previousStatus ? previousStatus : "draft"; const metaTrx = this.components.get(meta_trx_1.MetaTrx); await metaTrx.remove("post", { objectId: postId, key: "_wp_trash_meta_status", }); await metaTrx.remove("post", { objectId: postId, key: "_wp_trash_meta_time", }); const postUpdated = await this.upsert({ ID: postId, post_status: newStatus, }); if (!postUpdated) { return false; } await this.untrashComments(post); return post; } // wp_untrash_post_comments async untrashComments(postIdOrPost) { let post; if (typeof postIdOrPost == "number") { post = await this.postUtil.get(postIdOrPost); } else { post = postIdOrPost; } if (!post.props) { return false; } const postId = post.props.ID; const commentStatuses = await post.meta.get("_wp_trash_meta_comments_status"); if (!commentStatuses) { return true; } const groupByStatus = new Map(); for (const [k, v] of Object.entries(commentStatuses)) { groupByStatus.set(`${v}`, [ ...(groupByStatus.get(`${v}`) ?? []), parseInt(k), ]); } for (const [k, v] of groupByStatus.entries()) { const trx = await this.database.transaction; try { await trx .table(this.tables.get("comments")) .whereIn("comment_ID", v) .update({ comment_approved: k, }); } catch (e) { trx.rollback(); throw new Error(`Failed to update post comments - ${e}`); } await trx.commit(); } const metaTrx = this.components.get(meta_trx_1.MetaTrx); await metaTrx.remove("post", { objectId: postId, key: "_wp_trash_meta_comments_status", }); return true; } // wp_trash_post async trash(postId) { const EMPTY_TRASH_DAYS = this.config.config.constants.EMPTY_TRASH_DAYS; const post = await this.postUtil.get(postId); if (!post.props || "trash" == post.props.post_status) { return undefined; } if (!EMPTY_TRASH_DAYS) { await this.remove(postId); return post; } const previousStatus = post.props.post_status; const metaTrx = this.components.get(meta_trx_1.MetaTrx); await metaTrx.upsert("post", postId, "_wp_trash_meta_status", previousStatus); await metaTrx.upsert("post", postId, "_wp_trash_meta_time", (0, common_1.currentUnixTimestamp)()); const postUpdated = await this.upsert({ ID: postId, post_status: "trash", }); if (!postUpdated) { return undefined; } await this.trashComments(postId); return post; } // wp_trash_post_comments async trashComments(postOrId) { const post = typeof postOrId == "number" ? await this.postUtil.get(postOrId) : postOrId; if (!post?.props) { return false; } const postId = post.props.ID; const queryUtil = this.components.get(query_util_1.QueryUtil); const comments = await queryUtil.comments((query) => { query.where("post_ID", postId); }, zod_1.z.array(val.database.wpComments.pick({ comment_ID: true, comment_approved: true, }))); if (!comments) { return false; } const statuses = {}; comments.forEach((comments) => { statuses[comments.comment_ID] = comments.comment_approved; }); const metaTrx = this.components.get(meta_trx_1.MetaTrx); await metaTrx.upsert("post", postId, "_wp_trash_meta_comments_status", statuses, { serialize: true, }); // Set status for all comments to post-trashed. const trx = await this.database.transaction; let result = 0; try { await trx .table(this.tables.get("comments")) .where("comment_post_ID", postId) .update({ comment_approved: "post-trashed", }) .then((v) => { result = v; }); } catch (e) { trx.rollback(); throw new Error(`Failed to update post comments - ${e}`); } await trx.commit(); return result; } // update_attached_file async syncAttachedFile(postId, file) { const post = await this.postUtil.get(postId); if (!post.props) { return; } const staticAssetsPath = this.config.config.staticAssetsPath; file = file .replace(new RegExp(`^${staticAssetsPath}`), "") .replace(/^\/+/, ""); const metaTrx = this.components.get(meta_trx_1.MetaTrx); if (file.length > 0) { await metaTrx.upsert("post", postId, "_wp_attached_file", file); } else { await metaTrx.remove("post", { objectId: postId, key: "_wp_attached_file", }); } } // wp_set_post_categories async syncCategories(postId, namesOrTermIds, append = false) { const post = await this.postUtil.get(postId); if (!post.props) { return; } if (0 >= namesOrTermIds.length) { const taxonomy = await this.taxonomyUtil.get("category"); if (!taxonomy.props?.default_term) { return; } if ("auto-draft" !== post.props.post_status) { namesOrTermIds = [taxonomy.props?.default_term]; } } const termTrx = this.components.get(term_trx_1.TermTrx); return await termTrx.syncObject(postId, namesOrTermIds, "category", append); } async syncTerms(postId, slugsOrTermIds, taxonomyName = "post_tag", append = false) { const post = await this.postUtil.get(postId); if (!post.props) { return; } /* * Hierarchical taxonomies must always pass IDs rather than names so that * children with the same names but different parents aren't confused. */ if (await this.taxonomyUtil.isHierarchical(taxonomyName)) { slugsOrTermIds = slugsOrTermIds.map((slugOrTermId) => typeof slugOrTermId == "string" ? parseInt(slugOrTermId) : slugOrTermId); } const termTrx = this.components.get(term_trx_1.TermTrx); return await termTrx.syncObject(postId, slugsOrTermIds, taxonomyName, append); } }; exports.PostTrx = PostTrx; exports.PostTrx = PostTrx = __decorate([ (0, component_1.transactions)(), __metadata("design:paramtypes", [database_1.default, logger_1.Logger, components_1.Components, config_1.Config, post_util_1.PostUtil, taxonomy_util_1.TaxonomyUtil, comment_util_1.CommentUtil // private validator: Validator ]) ], PostTrx);