UNPKG

@rnaga/wp-node

Version:

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

273 lines (272 loc) • 11.3 kB
"use strict"; 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 __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.PostUtil = void 0; const config_1 = require("../../config"); const component_1 = require("../../decorators/component"); const components_1 = require("../components"); const current_1 = require("../current"); const post_1 = require("../post"); const query_util_1 = require("./query.util"); let PostUtil = class PostUtil { config; components; constructor(config, components) { this.config = config; this.components = components; } toPost(post) { return this.components.get(post_1.Post, [post.ID, post]); } toPosts(posts) { return posts.map((post) => this.toPost(post)); } async get(id) { return await this.components.asyncGet(post_1.Post, [id]); } async getBySlug(slug) { const queryUtil = this.components.get(query_util_1.QueryUtil); const posts = await queryUtil.posts((query) => query.where("post_name", slug).builder.limit(1)); const postId = posts?.[0]?.ID; return postId ? await this.get(postId) : undefined; } // is_post_publicly_viewable async isPubliclyViewable(postIdOrPost) { const post = typeof postIdOrPost == "number" ? await this.get(postIdOrPost) : postIdOrPost; if (!post.props?.ID || 0 >= post.props.ID) { return false; } return (this.isTypeViewable(post.props.post_type) && this.isStatusViewable(post.props.post_status)); } getViewableTypes() { return Object.keys(this.config.config.posts.types).filter((type) => this.isTypeViewable(type)); } // is_post_type_viewable isTypeViewable(typeObjectOrString) { const typeObject = typeof typeObjectOrString === "string" ? this.getTypeObject(typeObjectOrString) : typeObjectOrString; if (!typeObject) { return false; } return (typeObject.publiclyQueryable || (typeObject._builtin && typeObject.public)); } // https://github.com/WordPress/WordPress/blob/master/wp-includes/post.php // is_post_status_viewable isStatusViewable(statusObjectOrString) { const statusObject = typeof statusObjectOrString === "string" ? this.getStatusObject(statusObjectOrString) : statusObjectOrString; if (!statusObject || true == statusObject.internal || true == statusObject.protected) { return false; } return true == statusObject._builtin && true == statusObject.public; } // https://github.com/WordPress/WordPress/blob/master/wp-includes/post.php // get_post_status_object getStatusObject(status) { return !status || !this.config.config.posts.statuses[status] ? undefined : this.config.config.posts.statuses[status]; } // https://github.com/WordPress/WordPress/blob/master/wp-includes/post.php // get_post_status async getStatus(post, parent) { if (!post?.props) { const current = this.components.get(current_1.Current); if (!current.post) { return undefined; } post = current.post; } const postParent = parent ?? (await this.components.asyncGet(post_1.Post, [post.props?.post_parent])); let postStatus = post.props?.post_status; if ("attachment" === post.props?.post_type && "inherit" === postStatus) { if (0 === post.props.post_parent || !postParent.props || post.props.ID === post.props.post_parent) { // Unattached attachments with inherit status are assumed to be published. postStatus = "publish"; } else if ("trash" === (await this.getStatus(postParent))) { // Get parent status prior to trashing. postStatus = await postParent.meta.get("_wp_trash_meta_status"); if (!postStatus) { // Assume publish as above. postStatus = "publish"; } } else { postStatus = await this.getStatus(postParent); } } else if ("attachment" === post.props?.post_type && !["private", "trash", "auto-draft"].includes(post.props?.post_status ?? "")) { /* * Ensure uninherited attachments have a permitted status either 'private', 'trash', 'auto-draft'. * This is to match the logic in wp_insert_post(). * * Note: 'inherit' is excluded from this check as it is resolved to the parent post's * status in the logic block above. */ postStatus = "publish"; } return postStatus; } // get_attached_file // eslint-disable-next-line @typescript-eslint/no-unused-vars async getAttachedFile(postId, unfiltered = false) { const post = await this.get(postId); if (!post.props) { return undefined; } let file = await post.meta.get("_wp_attached_file"); if (!file) { return undefined; } // If the file is relative, prepend upload dir. if (file && !file.startsWith("/") && !/^.:\\/.test(file)) { file = `${this.config.config.staticAssetsPath}/${file}`; } return file; } // wp_get_attachment_metadata async getAttachmentMetadata(postId) { const post = await this.get(postId); if (!post.props) { return undefined; } const meta = await post.meta.get("_wp_attachment_metadata"); if (!meta) { return undefined; } return meta; } getTypeObject(name) { const type = this.config.config.posts.types[name]; if (!type) { return undefined; } type.capabilities = { ...(type.capabilities ?? {}), ...this.getCapabilities(type), }; return type; } // get_post_type_capabilities getCapabilities(args) { const capabilityType = !Array.isArray(args?.capabilityType) ? [args.capabilityType, args.capabilityType + "s"] : args.capabilityType; // Singular base for meta capabilities, plural base for primitive capabilities. const [singular_base, plural_base] = capabilityType; let defaultCapabilities = { // Meta capabilities. edit_post: "edit_" + singular_base, read_post: "read_" + singular_base, delete_post: "delete_" + singular_base, // Primitive capabilities used outside of map_meta_cap(): edit_posts: "edit_" + plural_base, edit_others_posts: "edit_others_" + plural_base, delete_posts: "delete_" + plural_base, publish_posts: "publish_" + plural_base, read_private_posts: "read_private_" + plural_base, }; // Primitive capabilities used within map_meta_cap(): if (args.mapMetaCap) { defaultCapabilities = { ...defaultCapabilities, ...{ read: "read", delete_private_posts: "delete_private_" + plural_base, delete_published_posts: "delete_published_" + plural_base, delete_others_posts: "delete_others_" + plural_base, edit_private_posts: "edit_private_" + plural_base, edit_published_posts: "edit_published_" + plural_base, }, }; } const capabilities = { ...defaultCapabilities, ...(args.capabilities ?? {}), }; // Post creation capability simply maps to edit_posts by default: if (!capabilities || !capabilities["create_posts"]) { capabilities["create_posts"] = capabilities["edit_posts"]; } return capabilities; } // wp_unique_post_slug async getUniqueSlug(slug, post, maxSuffix = 10) { const queryUtil = this.components.get(query_util_1.QueryUtil); if (typeof post === "number") { post = await this.get(post); } slug = slug?.trim(); const postId = post.props?.ID ?? 0; const postParent = post.props?.post_parent ?? 0; const postType = post.props?.post_type ?? ""; const postStatus = post.props?.post_status ?? ""; const postTypeObject = this.getTypeObject(postType); if (["draft", "pending", "auto-draft"].includes(postStatus) || ("inherit" === postStatus && "revision" === postType) || "user_request" === postType || ("nav_menu_item" == postType && postTypeObject?.hierarchical)) { return slug ?? post.props?.post_name; } slug = this.truncateSlug(slug); if (!slug || 0 >= slug.length) { return slug; } for (let suffix = 0; suffix < maxSuffix; suffix++) { const newSlug = 0 >= suffix ? slug : `${slug}-${suffix + 1}`; const posts = await queryUtil.posts((query) => { query .where("post_name", newSlug) .builder.not.__ref(query) .where("ID", postId); if (postTypeObject?.hierarchical) { query .whereIn("post_type", ["attachment", postType]) .where("post_parent", postParent); } }); if (!posts) { return newSlug; } } return `${slug}-${Math.floor(Math.random() * (maxSuffix + 999990010 - maxSuffix + 1) + maxSuffix + 1)}`; } // _truncate_post_slug truncateSlug(slug, length = 200) { if (slug.length > length) { const decodedSlug = decodeURIComponent(slug); if (decodedSlug === slug) { slug = slug.substring(0, length); } else { slug = encodeURIComponent(decodedSlug).slice(0, length); } } return slug.replace(/-+$/, ""); // Remove trailing hyphens } }; exports.PostUtil = PostUtil; exports.PostUtil = PostUtil = __decorate([ (0, component_1.component)(), __metadata("design:paramtypes", [config_1.Config, components_1.Components]) ], PostUtil);