diff --git a/server/publications/collections/media.js b/server/publications/collections/media.js index 8dc2daeb2f2..ddd872fe39d 100644 --- a/server/publications/collections/media.js +++ b/server/publications/collections/media.js @@ -72,9 +72,7 @@ Meteor.publish("Media", function (shops) { }); } - return Media.find(selector, { - sort: { - "metadata.priority": 1 - } + return Media.find({ + "metadata.type": "brandAsset" }); }); diff --git a/server/publications/collections/product.js b/server/publications/collections/product.js index 022abf1d61d..c5b9d0c7bc7 100644 --- a/server/publications/collections/product.js +++ b/server/publications/collections/product.js @@ -1,7 +1,45 @@ -import { Products, Revisions } from "/lib/collections"; +import { Media, Products, Revisions } from "/lib/collections"; import { Logger, Reaction } from "/server/api"; import { RevisionApi } from "/imports/plugins/core/revisions/lib/api/revisions"; +export function findProductMedia(publicationInstance, productIds) { + const shopId = Reaction.getShopId(); + const selector = {}; + + if (!shopId) { + return publicationInstance.ready(); + } + + if (Array.isArray(productIds)) { + selector["metadata.productId"] = { + $in: productIds + }; + } else { + selector["metadata.productId"] = productIds; + } + + if (shopId) { + selector["metadata.shopId"] = shopId; + } + + // No one needs to see archived images on products + selector["metadata.workflow"] = { + $nin: ["archived"] + }; + + // Product editors can see both published and unpublished images + if (!Reaction.hasPermission(["createProduct"], publicationInstance.userId)) { + selector["metadata.workflow"].$in = [null, "published"]; + } + + return Media.find(selector, { + sort: { + "metadata.priority": 1 + } + }); +} + + /** * product detail publication * @param {String} productId - productId or handle @@ -71,7 +109,10 @@ Meteor.publish("Product", function (productId) { }; if (RevisionApi.isRevisionControlEnabled()) { - const handle = Products.find(selector).observeChanges({ + const productCursor = Products.find(selector); + const productIds = productCursor.map(p => p._id); + + const handle = productCursor.observeChanges({ added: (id, fields) => { const revisions = Revisions.find({ "documentId": id, @@ -156,13 +197,29 @@ Meteor.publish("Product", function (productId) { handle2.stop(); }); - return this.ready(); + return [ + findProductMedia(this, productIds) + ]; } - // Revision control is disabled - return Products.find(selector); + // Revision control is disabled, but is an admin + const productCursor = Products.find(selector); + const productIds = productCursor.map(p => p._id); + const mediaCursor = findProductMedia(this, productIds); + + return [ + productCursor, + mediaCursor + ]; } // Everyone else gets the standard, visibile products and variants - return Products.find(selector); + const productCursor = Products.find(selector); + const productIds = productCursor.map(p => p._id); + const mediaCursor = findProductMedia(this, productIds); + + return [ + productCursor, + mediaCursor + ]; }); diff --git a/server/publications/collections/products.js b/server/publications/collections/products.js index 3dce1e564fa..60a385b2565 100644 --- a/server/publications/collections/products.js +++ b/server/publications/collections/products.js @@ -1,6 +1,7 @@ import { Products, Revisions } from "/lib/collections"; import { Reaction, Logger } from "/server/api"; import { RevisionApi } from "/imports/plugins/core/revisions/lib/api/revisions"; +import { findProductMedia } from "./product"; // // define search filters as a schema so we can validate @@ -273,7 +274,8 @@ Meteor.publish("Products", function (productScrollLimit = 24, productFilters, so } if (RevisionApi.isRevisionControlEnabled()) { - const handle = Products.find(newSelector).observeChanges({ + const productCursor = Products.find(newSelector); + const handle = productCursor.observeChanges({ added: (id, fields) => { const revisions = Revisions.find({ "$or": [ @@ -366,13 +368,25 @@ Meteor.publish("Products", function (productScrollLimit = 24, productFilters, so handle2.stop(); }); - return this.ready(); + const mediaProductIds = productCursor.fetch().map((p) => p._id); + const mediaCursor = findProductMedia(this, mediaProductIds); + + return [ + mediaCursor + ]; } - // Revision control is disabled - return Products.find(newSelector, { + // Revision control is disabled, but is admin + const productCursor = Products.find(newSelector, { sort: sort, limit: productScrollLimit }); + const mediaProductIds = productCursor.fetch().map((p) => p._id); + const mediaCursor = findProductMedia(this, mediaProductIds); + + return [ + productCursor, + mediaCursor + ]; } // Everyone else gets the standard, visible products @@ -406,11 +420,19 @@ Meteor.publish("Products", function (productScrollLimit = 24, productFilters, so }); } // Returning Complete product tree for top level products to avoid sold out warning. - return Products.find( - { - $or: [ { _id: { $in: productIds } }, - { ancestors: { $in: productIds } } - ] - }); + const productCursor = Products.find({ + $or: [ + { _id: { $in: productIds } }, + { ancestors: { $in: productIds } } + ] + }); + + const mediaProductIds = productCursor.fetch().map((p) => p._id); + const mediaCursor = findProductMedia(this, mediaProductIds); + + return [ + productCursor, + mediaCursor + ]; } });