const Category = require("../models/Category"); const Content = require("../models/Content"); const { body, validationResult } = require("express-validator"); const { _sr } = require("../plugins/serverResponses"); const { res404, res500, checkValidations, } = require("../plugins/controllersHelperFunctions"); const News = require("../models/News"); const sharp = require("sharp"); const fs = require("fs"); const { extname } = require("path"); // variables const titleFilterRegex = new RegExp("/", "g"); const noCover = "/img/no-cover.jpg"; const coverNewsWidth = 400; const coverNewsHeight = 400; const coverQuality = 100; ////////////////// functions const _customTitle = async (categories) => { try { const newCatArr = []; for (const item of categories) { const title = []; const treeCat = item.treeCat; for (let i = treeCat.length - 1; i >= 0; i--) { title.push(treeCat[i].title); } title.push(item.title); item.title = title.join(" >> "); newCatArr.push(item); } return newCatArr; } catch (error) { console.log(error); return []; } }; /** یک آرایه داریم که خونه اول رو میگیریم و میریزیم داخل آرایه جدید بعد داخل فور دوم کل آرایه رو طی میکنیم * و اونایی که قسمتی از تایتل دیتای پوش شده داخل آرایه جدید رو دارن داخل این آرایه جدید پوش میکنیم */ // todo this is peace of shit please change it in future const _sortedCategory = async (categories) => { try { let sortedArr = []; // let clone = JSON.parse(JSON.stringify(categories)); // // for (const cat of clone) { // if (cat.parent){ // let getParent = categories.find(item => item._id === cat.parent._id) // } // } for (let i = 0; i < categories.length; i++) { if (!sortedArr.includes(categories[i]) && !categories[i].parent) { sortedArr.push(categories[i]); } for (let j = 0; j < categories.length; j++) { if ( categories[i].childs.includes(categories[j]._id) && !sortedArr.includes(categories[j]) ) { sortedArr.push(categories[j]); } } } if (sortedArr.length !== categories.length) { for (const cat of categories) { if (!sortedArr.includes(cat)) { sortedArr.push(cat); } } } return sortedArr; } catch (error) { console.log(error); return []; } }; const _checkSpecPermission = async (req, category) => { return ( !req.user.specialPermissions.includes(category._id) && //check parent id exist in special permissions or not !req.user.specialPermissions.some((item) => category?.treeCat?.join().includes(item) ) ); }; /////////////////////////////////////////////////////////////////////// admin module.exports.addCategory = [ [ body("title") .notEmpty() .withMessage(_sr["fa"].required.title) .custom((value, { req }) => { return Category.findOne({ title: value, }).then((category) => { if (category) return Promise.reject(_sr["fa"].duplicated.title); else return true; }); }), body("parent") .optional() .isString() .withMessage(`parent ${_sr["fa"].optional.string}`), // body('showInMenu') // .isBoolean().withMessage(_sr['fa'].format.boolean), body("navIndex") .optional() .isNumeric() .withMessage(_sr["fa"].format.number), body("priority").isNumeric().withMessage(_sr["fa"].format.number), // body('showInSectionOne') // .optional().isBoolean().withMessage(_sr['fa'].format.boolean), // // body('showInSectionTwo') // .optional().isBoolean().withMessage(_sr['fa'].format.boolean), // // body('showInSectionThree') // .optional().isBoolean().withMessage(_sr['fa'].format.boolean), body("siteMap").isBoolean().withMessage(_sr["fa"].format.boolean), body("special").isBoolean().withMessage(_sr["fa"].format.boolean), body("url") .optional() .isString() .withMessage(`url ${_sr["fa"].optional.string}`), body("pageContent") .optional() .isString() .withMessage(`pageContent ${_sr["fa"].optional.string}`), body("news").optional().isBoolean().withMessage(_sr["fa"].format.boolean), body("child").optional().isBoolean().withMessage(_sr["fa"].format.boolean), body("hasNewsTab") .optional() .isBoolean() .withMessage(_sr["fa"].format.boolean), body("hasContentTab") .optional() .isBoolean() .withMessage(_sr["fa"].format.boolean), body("hasMediaTab") .optional() .isBoolean() .withMessage(_sr["fa"].format.boolean), body("hasSubMenusTab") .optional() .isBoolean() .withMessage(_sr["fa"].format.boolean), body("hasTermsTab") .optional() .isBoolean() .withMessage(_sr["fa"].format.boolean), body("hasNotificationsTab") .optional() .isBoolean() .withMessage(_sr["fa"].format.boolean), body("hasSpecNewsTab") .optional() .isBoolean() .withMessage(_sr["fa"].format.boolean), body("hasNazarTab") .optional() .isBoolean() .withMessage(_sr["fa"].format.boolean), body("hasNewsFileTab") .optional() .isBoolean() .withMessage(_sr["fa"].format.boolean), body("modelType").custom((value, { req }) => { if (req.user.portals.join() === portal.join()) { if (!portal.includes(value)) { return Promise.reject(_sr["fa"].required.field); } else { return true; } } else { return true; } }), ], checkValidations(validationResult), async (req, res) => { try { let { title, parent, // showInMenu, navIndex, priority, // showInSectionOne, // showInSectionTwo, // showInSectionThree, siteMap, special, modelType, showInFooter, url, pageContent, news, child, hasNewsTab, hasContentTab, hasMediaTab, hasSubMenusTab, hasTermsTab, hasNotificationsTab, hasSpecNewsTab, hasNazarTab, hasNewsFileTab, defaultPageType, hasManagerInfo, managerName, managerDescription, } = req.body; ///////////// permissions if (req.user.specialPermissions.length && _.isEmpty(parent)) { return res.status(403).json({ message: `شما مجاز به اضافه کردن دسته بندی اصلی نیستید`, }); } // if (req.user.specialPermissions.length && !_.isEmpty(parent) && !req.user.permissions.includes('categories-add')){ // return res.status(403).json(`شما اجازه اضافه کردن یک دسته بندی جدید را ندارید`); // } /** set portals */ modelType = req.user.portals.join() === portal.join() ? modelType : req.user.portals[0]; /** only one category can be in to the section one and two */ // if (showInSectionOne === true) { // await _checkOtherSection('one'); // } // // if (showInSectionTwo === true) { // await _checkOtherSection('two'); // } const catData = { title: title.trim().replace(titleFilterRegex, "-"), priority: priority, parent: parent || null, // showInMenu: showInMenu, navIndex: navIndex, siteMap: siteMap, special: special, showInFooter, url, // showInSectionOne, // showInSectionTwo, // showInSectionThree, pageContent, modelType, news, child, hasNewsTab, hasContentTab, hasMediaTab, hasSubMenusTab, hasTermsTab, hasNotificationsTab, hasSpecNewsTab, hasNazarTab, hasNewsFileTab, defaultPageType, hasManagerInfo, managerName, managerDescription, _creator: req.user._id, _updatedBy: req.user._id, }; let getParent; if (parent) { /** * check parent exist or not */ getParent = await Category.findById(parent); // .populate({ // path: 'parent', // populate: { // path: 'parent', // model: 'Category' // } // }); /** * if not found show error */ if (!getParent) return res404(res, `دسته بندی پدر پیدا نشد`); ////// start permissions /** check special permission */ if ( req.user.specialPermissions.length && (await _checkSpecPermission(req, getParent)) ) { return res.status(403).json({ message: `شما اجازه اضافه کردن فرزند جدید برای این دسته بندی را ندارید`, }); } /** check can add child */ if (!getParent.child) return res .status(403) .json({ message: `این دسته بندی نمی تواند زیرمجموعه داشته باشد` }); /** check access portal */ if (!req.user.portals.includes(getParent.modelType)) return res.status(403).json({ message: `شما اجازه انتخاب این دسته بندی را ندارید`, }); /** check type */ if (getParent.modelType !== modelType) return res500( res, `شما اجازه استفاده این دسته بندی به عنوان سردسته را ندارید` ); ////// end permissions /** * add level of new category */ catData.level = Number(getParent.level) + 1; /** add tree cat */ // catData.treeCat = await _makeTreeCat(getParent); const treeCatClone = JSON.parse(JSON.stringify(getParent.treeCat)); treeCatClone.push(getParent._id); catData.treeCat = treeCatClone; catData.rootParent = getParent.rootParent || getParent._id; } /** * add new category */ const create = await Category.create(catData); /** * check added or not */ if (!create) return res500( res, `مشکلی در ثبت اطلاعات پیش آمده لطفا دوباره تلاش کنید` ); /** * if have parent should added new category in child of parent category * and set level for new category */ if (getParent) { /** * add new category for parent */ getParent.childs.push(create._id); await getParent.save(); } if (req.files?.managerCover) { const image = req.files.managerCover; if (!_sr.supportedImageFormats.includes(image.mimetype.split("/")[1])) { return res.status(422).json({ validation: { cover: { msg: _sr["fa"].format.image, }, }, }); } const imageName = `manager_${Date.now()}_${create._id}.${ image.mimetype.split("/")[1] }`; try { const target = sharp(image.data); await target .resize(coverNewsWidth, coverNewsHeight, { fit: "cover" }) .jpeg({ quality: coverQuality }) .toFile(`./static/uploads/images/category/${imageName}`); /** * if exist old pic delete it from file */ // if (targetNews.cover !== noCover && !targetNews.imported) { // let oldPic = `./static${targetNews.cover}`; // // if (await fs.existsSync(oldPic)) { // fs.unlink(oldPic, (err) => { // if (err) return res500(res, err?.message); // }); // } // } // if (targetNews.thumbCover !== noCover && !targetNews.imported) { // let oldPic = `./static${targetNews.thumbCover}`; // // if (await fs.existsSync(oldPic)) { // fs.unlink(oldPic, (err) => { // if (err) return res500(res, err?.message); // }); // } // } create.managerCover = imageName; await create.save(); } catch (e) { return res500(res, e?.message); } } if (req.files?.icon) { const image = req.files.icon; if (!_sr.supportedImageFormats.includes(image.mimetype.split("/")[1])) { return res.status(422).json({ validation: { cover: { msg: _sr["fa"].format.image, }, }, }); } const ext = extname(image.name); const imageName = `shafafiat_icon_${Date.now()}${ext}`; try { await image.mv( `${process.cwd()}/static/uploads/images/category/shafafiat/${imageName}` ); /** * if exist old pic delete it from file */ // if (targetNews.cover !== noCover && !targetNews.imported) { // let oldPic = `./static${targetNews.cover}`; // // if (await fs.existsSync(oldPic)) { // fs.unlink(oldPic, (err) => { // if (err) return res500(res, err?.message); // }); // } // } // if (targetNews.thumbCover !== noCover && !targetNews.imported) { // let oldPic = `./static${targetNews.thumbCover}`; // // if (await fs.existsSync(oldPic)) { // fs.unlink(oldPic, (err) => { // if (err) return res500(res, err?.message); // }); // } // } create.icon = imageName; await create.save(); } catch (e) { return res500(res, e?.message); } } /** * show result */ return res.json(create); } catch (error) { console.log(error); /** * if we got unkown error show to client */ res500(res, error.message); } }, ]; module.exports.updateCategory = [ [ body("title").notEmpty().withMessage(_sr["fa"].required.title), // body('parent') // .optional().isString().withMessage(`parent ${_sr['fa'].optional.string}`), // body('showInMenu') // .isBoolean().withMessage(_sr['fa'].format.boolean), body("navIndex").isNumeric().withMessage(_sr["fa"].format.number), body("priority").isNumeric().withMessage(_sr["fa"].format.number), // body('showInSectionOne') // .optional().isBoolean().withMessage(_sr['fa'].format.boolean), // body('showInSectionTwo') // .optional().isBoolean().withMessage(_sr['fa'].format.boolean), // body('showInSectionThree') // .optional().isBoolean().withMessage(_sr['fa'].format.boolean), body("siteMap").isBoolean().withMessage(_sr["fa"].format.boolean), body("special").isBoolean().withMessage(_sr["fa"].format.boolean), body("showInFooter") .isNumeric() .withMessage(_sr["fa"].format.number) .bail() .isIn([0, 1, 2, 3]) .withMessage(`از بین اعداد 1و2و3 یک عدد ارسال کنید`), body("url") .optional() .isString() .withMessage(`url ${_sr["fa"].optional.string}`), body("pageContent") .optional() .isString() .withMessage(`pageContent ${_sr["fa"].optional.string}`), body("news").optional().isBoolean().withMessage(_sr["fa"].format.boolean), body("child").optional().isBoolean().withMessage(_sr["fa"].format.boolean), body("hasNewsTab") .optional() .isBoolean() .withMessage(_sr["fa"].format.boolean), body("hasContentTab") .optional() .isBoolean() .withMessage(_sr["fa"].format.boolean), body("hasMediaTab") .optional() .isBoolean() .withMessage(_sr["fa"].format.boolean), body("hasSubMenusTab") .optional() .isBoolean() .withMessage(_sr["fa"].format.boolean), body("hasTermsTab") .optional() .isBoolean() .withMessage(_sr["fa"].format.boolean), body("hasNotificationsTab") .optional() .isBoolean() .withMessage(_sr["fa"].format.boolean), body("hasSpecNewsTab") .optional() .isBoolean() .withMessage(_sr["fa"].format.boolean), body("hasNazarTab") .optional() .isBoolean() .withMessage(_sr["fa"].format.boolean), body("hasNewsFileTab") .optional() .isBoolean() .withMessage(_sr["fa"].format.boolean), ], checkValidations(validationResult), async (req, res) => { try { /** * get data from input */ let { title, parent, // showInMenu, navIndex, priority, // showInSectionOne, // showInSectionTwo, // showInSectionThree, siteMap, special, showInFooter, url, pageContent, news, child, hasNewsTab, hasContentTab, hasMediaTab, hasSubMenusTab, hasTermsTab, hasNotificationsTab, hasSpecNewsTab, hasNazarTab, hasNewsFileTab, defaultPageType, hasManagerInfo, managerName, managerDescription, } = req.body; /** * get id */ const catId = req.params.id; ////////// permissions // if (req.user.specialPermissions.length && !req.user.permissions.includes('categories-update')){ // return res.status(403).json(`شما اجازه بروزرسانی این دسته بندی را ندارید`); // } /** * check category exist or not */ const targetCategory = await Category.findOne({ _id: catId, }); if (!targetCategory) return res404(res, `دسته بندی مورد نظر پیدا نشد`); /** check special permission */ if ( req.user.specialPermissions.length && (await _checkSpecPermission(req, targetCategory)) ) { return res.status(403).json({ message: `شما اجازه بروزرسانی این دسته بندی را ندارید`, }); } /** check access portal */ if (!req.user.portals.includes(targetCategory.modelType)) { return res.status(403).json({ message: `شما اجازه آپدیت این دسته بندی را ندارید`, }); } /** only one category can be in to the section one and two */ // if (showInSectionOne === 'true') { // targetCategory.showInSectionOne = await _checkOtherSection('one'); // } // if (showInSectionTwo === 'true') { // targetCategory.showInSectionTwo = await _checkOtherSection('two'); // } if (targetCategory.title !== title) { const checkDuppTitle = await Category.findOne({ title: title, }); if (checkDuppTitle) { return res.status(422).json({ validation: { title: { msg: _sr["fa"].duplicated.title } }, }); } } // if(parent != null && targetCategory.parent != null && parent != targetCategory.parent) { // /** check have news or not */ // var checkHaveNews = await News.find({allCat : [targetCategory._id]}); // if(checkHaveNews.length){ // return res.status(403).json({message :`این دسته بندی دارای اخبار می باشد و شما نمیتوانید دسته بندی والد آن را تغییر دهید لطفا ابتدا اخبار را حذف کرده سپس این کار را انجام دهید`}); // } // /** // * check new parent // */ // var newParentCategory = await Category.findOne({_id : parent}); // if(!newParentCategory){ // return res404(res,`دسته بندی انتخاب شده پیدا نشد`); // }; // if(newParentCategory.treeCat.includes(targetCategory._id)){ // return res.status(422).json({validation : {parent : {msg : ``}}}) // } // /** // * get category parent // */ // if(targetCategory.parent){ // var parentCategory = await Category.findOne({_id : targetCategory.parent}); // if(parentCategory){ // /** // * delete catId from old category // */ // const index = parentCategory.childs.indexOf(targetCategory._id); // if (index > -1) { // parentCategory.childs.splice(index, 1); // await parentCategory.save(); // } // } // } // if(!newParentCategory.child){ // return res.status(403).json({message :`این دسته بندی اجازه داشتن زیرمجموعه ندارد`}); // } // /** check access portal */ // if(!req.user.portals.includes(newParentCategory.modelType)){ // return res.status(403).json({message :`شما اجازه انتخاب این دسته بندی را ندارید`}); // } // /** check type */ // if(newParentCategory.modelType != modelType){ // return res.status(403).json({message :`شما اجازه استفاده این دسته بندی به عنوان سردسته را ندارید`}); // } // /** // * add catId for new parnet // */ // newParentCategory.childs.push(targetCategory._id); // await newParentCategory.save(); // /** // * update level // */ // targetCategory.level = newParentCategory.level + 1; // } /** * make update object */ targetCategory.title = title.trim().replace(titleFilterRegex, "-"); // targetCategory.showInMenu = showInMenu; targetCategory.navIndex = navIndex; targetCategory.priority = priority; // targetCategory.showInSectionOne = showInSectionOne; // targetCategory.showInSectionTwo = showInSectionTwo; // targetCategory.showInSectionThree = showInSectionThree; targetCategory.siteMap = siteMap; targetCategory.special = special; targetCategory._creator = req.user._id; targetCategory._updatedBy = req.user._id; targetCategory.showInFooter = showInFooter; targetCategory.pageContent = pageContent; targetCategory.child = child; targetCategory.url = url; targetCategory.news = news; targetCategory.hasNewsTab = hasNewsTab; targetCategory.hasContentTab = hasContentTab; targetCategory.hasMediaTab = hasMediaTab; targetCategory.hasSubMenusTab = hasSubMenusTab; targetCategory.hasTermsTab = hasTermsTab; targetCategory.hasNotificationsTab = hasNotificationsTab; targetCategory.hasSpecNewsTab = hasSpecNewsTab; targetCategory.hasNazarTab = hasNazarTab; targetCategory.hasNewsFileTab = hasNewsFileTab; targetCategory.defaultPageType = defaultPageType; targetCategory.hasManagerInfo = hasManagerInfo; targetCategory.managerName = managerName; targetCategory.managerDescription = managerDescription; if (req.files?.managerCover) { const image = req.files.managerCover; if (!_sr.supportedImageFormats.includes(image.mimetype.split("/")[1])) { return res.status(422).json({ validation: { cover: { msg: _sr["fa"].format.image, }, }, }); } const imageName = `manager_${Date.now()}_${targetCategory._id}.${ image.mimetype.split("/")[1] }`; try { const target = sharp(image.data); await target .resize(coverNewsWidth, coverNewsHeight, { fit: "cover" }) .jpeg({ quality: coverQuality }) .toFile(`./static/uploads/images/category/${imageName}`); /** * if exist old pic delete it from file */ if (targetCategory.managerCover !== noCover) { let oldPic = `./static${targetCategory.managerCover}`; if (await fs.existsSync(oldPic)) { fs.unlink(oldPic, (err) => { if (err) return res500(res, err?.message); }); } } targetCategory.managerCover = imageName; } catch (e) { return res500(res, e?.message); } } if (req.files?.icon) { const image = req.files.icon; console.log(image); if (!_sr.supportedImageFormats.includes(image.mimetype.split("/")[1])) { return res.status(422).json({ validation: { cover: { msg: _sr["fa"].format.image, }, }, }); } const ext = extname(image.name); const imageName = `shafafiat_icon_${Date.now()}${ext}`; try { await image.mv( `${process.cwd()}/static/uploads/images/category/shafafiat/${imageName}` ); // const target = sharp(image.data) // await target // .resize(coverNewsWidth, coverNewsHeight, {fit: 'cover'}) // .jpeg({quality: coverQuality}) // .toFile(`./static/uploads/images/category/shafafiat/${imageName}`); /** * if exist old pic delete it from file */ if (targetCategory.icon !== noCover) { let oldPic = `./static${targetCategory.icon}`; if (await fs.existsSync(oldPic)) { fs.unlink(oldPic, (err) => { if (err) return res500(res, err?.message); }); } } targetCategory.icon = imageName; console.log(targetCategory); } catch (e) { return res500(res, e?.message); } } await targetCategory.save(); /** * show result */ return res.json(targetCategory); } catch (error) { return res500(res, error.message); } }, ]; module.exports.deletOneCategory = [ async (req, res) => { try { const catId = req.params.id; /** * check category */ const targetCategory = await Category.findOne({ _id: catId, }); if (!targetCategory) { return res404(res, `دسته بندی مورد نظر پیدا نشد`); } /** check special permission */ if ( req.user.specialPermissions.length && (await _checkSpecPermission(req, targetCategory)) ) { return res.status(403).json({ message: `شما اجازه حذف این دسته بندی را ندارید`, }); } /** check access portal */ if (!req.user.portals.includes(targetCategory.modelType)) { return res.status(403).json({ message: `شما اجازه حذف این دسته بندی را ندارید`, }); } /** check special permissions */ if ( req.user.specialPermissions.includes(targetCategory._id) && !targetCategory.parent ) { return res.status(403).json({ message: `شما اجازه حذف این دسته بندی را ندارید`, }); } /** check owner ship */ if ( req.user.specialPermissions.includes(targetCategory._id) && targetCategory.parent !== req.user._id ) { return res.status(403).json({ message: `شما اجازه حذف این دسته بندی را ندارید`, }); } const checkHaveNews = await News.find({ allCat: [targetCategory._id], }); if (checkHaveNews.length) { return res.status(403).json({ message: `دسته بندی شما دارای خبر می باشد و قبل از حذف آن باید اخبار مربوط به این دسته بندی را حذف کنید`, }); } if (targetCategory.childs.length) { return res.status(403).json({ message: `دسته بندی مورد نظر دارای زیرمجموعه می باشد ابتدا زیرمجوعه ها را حذف کنید`, }); } /** * get category parent */ if (targetCategory.parent) { const categoryParent = await Category.findOne({ _id: targetCategory.parent, }); if (categoryParent) { /** * delete catId from category parent */ const index = categoryParent.childs.indexOf(targetCategory._id); if (index > -1) { categoryParent.childs.splice(index, 1); await categoryParent.save(); } } } /** * delete category */ targetCategory.delete(); /** * show result */ return res.json(targetCategory); } catch (error) { /** * if we got unkown error show to client */ res500(res, error); } }, ]; module.exports.deleteAllCategory = [ async (req, res) => { try { } catch (error) { /** * if we got unkown error show to client */ res500(res, error); } }, ]; module.exports.getOneCategory = [ async (req, res) => { try { const catId = req.params.id; /** * get category */ const targetCategory = await Category.findOne({ _id: catId, }); /** * if not exist */ if (!targetCategory) { return res404(res, `دسته بندی مورد نظر پیدا نشد`); } /** check access portal */ if (!req.user.portals.includes(targetCategory.modelType)) { return res.status(403).json({ message: `شما اجازه دسترسی به اطلاعات این دسته بندی را ندارید`, }); } /** * show result */ return res.json(targetCategory); } catch (error) { /** * if we got unkown error show to client */ res500(res, error); } }, ]; module.exports.getAll = [ async (req, res) => { try { const findQuery = {}; let populate = {}; if (req.user.specialPermissions.length) { findQuery._id = { $in: req.user.specialPermissions }; } else { findQuery.parent = null; // populate = { // path: 'childs', // populate: { // path: 'childs' // } // }; } if (req.user.portals.join() !== portal.join()) { findQuery.modelType = req.user.portals[0]; } /** * get all category */ const getAll = await Category.find(findQuery).populate("").sort({ navIndex: 1, }); /** * این قسمت ابجکت های تکراری را از بین میبره */ // if (req.user.specialPermissions.length) { // /** جدا کردن دسته بندی های اصلی */ // const parents = getAll.filter((item) => !item.parent); // /** جدا کردن دسته بندی های غیر اصلی */ // const nonParents = getAll.filter((item) => item.parent); // // /** با یک لوپ تو در تو اگر دسته بندی غیر اصلی در فرزندان دسته بندی اصلی وجود داشت حذف میشه */ // for (let i = 0; i < nonParents.length; i++) { // for (let j = 0; j < parents.length; j++) { // if (nonParents[i].treeCat.includes(parents[j]._id)) { // getAll.splice(getAll.findIndex(item => item._id === nonParents[i]._id), 1); // } // } // } // } /** * show result */ return res.json(getAll); } catch (error) { return res500(res, error.message); } }, ]; module.exports.search = [ async (req, res) => { try { const term = req.body?.term?.toString().trim() || ""; /** * search */ const search = await Category.find({ title: { $regex: ".*" + term + ".*", $options: "i", }, modelType: "normal", type: "category", }); /** * show result */ return res.json(search); } catch (error) { return res500(res, error.message); } }, ]; module.exports.permissions = [ async (req, res) => { try { const type = req.query.type; const findQuery = type ? { modelType: type, } : {}; const categories = await Category.find(findQuery) .populate("treeCat") .sort({ navIndex: 1 }) .lean(); let changeTitles = await _customTitle(categories); let sortedCats = await _sortedCategory(changeTitles); return res.json(sortedCats); } catch (error) { res500(res, error?.message); } }, ]; module.exports.getParent = [ async (req, res) => { try { const findQuery = {}; const type = req.query.type; // findQuery.parent = null; if (req.user.specialPermissions.length) { findQuery.$or = [ { _id: { $in: req.user.specialPermissions, }, }, ]; } if (req.user.portals.length) { findQuery.modelType = { $in: req.user.portals, }; } if (type && type === "news") { findQuery.news = true; } if (type && type === "child") { findQuery.child = true; } /** * get all category */ const getAll = await Category.find(findQuery) .populate("parent") .populate("treeCat") .sort({ navIndex: 1 }); let changeTitles = await _customTitle(getAll); let sortedCats = await _sortedCategory(changeTitles); /** * show result */ return res.json(sortedCats); } catch (error) { return res500(res, error?.message); } }, ]; //////////// add attachment file to category module.exports.addTermsFileToCategory = [ [body("termsTitle").notEmpty().withMessage(_sr["fa"].required.title)], checkValidations(validationResult), (req, res) => { if (!req.files?.file) return res .status(422) .json({ validation: { file: { msg: _sr["fa"].required.file } } }); if (req.files?.file.mimetype.split("/")[1] !== "pdf") return res .status(422) .json({ validation: { file: { msg: "فقط فرمت PDF قابل قبول است" } } }); const data = { title: req.body.termsTitle }; const file = req.files.file; const fileName = req.body.termsTitle.replace(titleFilterRegex, "-") + "_" + Date.now() + ".pdf"; file.mv(`./static/uploads/files/terms/${fileName}`); data.file = fileName; Category.findById(req.params.categoryId, (err, category) => { if (err || !category) return res404(res, err); category.terms.push(data); category.save((err) => { if (err) return res500(res, err); else return res.json({ message: _sr["fa"].response.success_save }); }); }); }, ]; module.exports.removeTermsFileFromCategory = [ (req, res) => { Category.findOne({ "terms._id": req.params.fileId }, (err, category) => { if (err || !category) return res404(res, err); const file = category.terms.id(req.params.fileId); if (!file) return res404(res, "not found"); file.remove(); fs.unlink(`./static/${file.file}`, (err) => { if (err) console.log(err); }); category.save((err) => { if (err) return res500(res, err); else return res.json({ message: _sr["fa"].response.success_remove }); }); }); }, ]; /////////////////////////////////////////////////////////////////////// public module.exports.getMenu = [ async (req, res) => { try { const portal = req.query?.portal || "ostandari"; const findQuery = { parent: null, // showInMenu: true, modelType: portal, }; let result = {}; /** * get all category */ const getAll = await Category.find(findQuery) .populate("treeCat") .sort({ navIndex: 1, // created_at: 1 }) .select("title childs navIndex url modelType treeCat defaultPageType"); /// get all page content const getContent = await Content.find({ showInMenu: true }); result.categories = getAll; result.staticContents = !!getContent.length; /** * show result */ return res.json(result); } catch (error) { return res500(res, error.message); } }, ];