diff --git a/admin/blocks/main.php b/admin/blocks/main.php index bf75b3dd45..2a188bc3b9 100644 --- a/admin/blocks/main.php +++ b/admin/blocks/main.php @@ -222,7 +222,7 @@ public function getMatchingBrizyBlocks($wpPost = null) } else { $template = Brizy_Admin_Templates::instance()->getTemplateForCurrentPage(); - if ($template) { + if ($template) { $ruleMatches = $this->getTemplateRuleMatches($template->getWpPost()); } else { $ruleMatches[] = [ diff --git a/composer.lock b/composer.lock index 7598503b8c..ca14b0c17b 100644 --- a/composer.lock +++ b/composer.lock @@ -11,7 +11,7 @@ "version": "dev-master", "source": { "type": "git", - "url": "https://github.com/bagrinsergiu/brizy-merge-page-assets.git", + "url": "git@github.com:bagrinsergiu/brizy-merge-page-assets.git", "reference": "61eea2244cb34ff8666b802aafa74f74dec869da" }, "dist": { @@ -40,10 +40,6 @@ "brizy", "brizy merge assets" ], - "support": { - "source": "https://github.com/bagrinsergiu/brizy-merge-page-assets/tree/master", - "issues": "https://github.com/bagrinsergiu/brizy-merge-page-assets/issues" - }, "time": "2022-09-27T14:56:05+00:00" }, { @@ -51,7 +47,7 @@ "version": "1.5.4", "source": { "type": "git", - "url": "https://github.com/bagrinsergiu/brizy-migration-utils.git", + "url": "git@github.com:bagrinsergiu/brizy-migration-utils.git", "reference": "81523e89975e56d192bb3a5622ddbe1d06e10809" }, "dist": { @@ -81,10 +77,6 @@ } ], "description": "Data migration utils", - "support": { - "source": "https://github.com/bagrinsergiu/brizy-migration-utils/tree/1.5.4", - "issues": "https://github.com/bagrinsergiu/brizy-migration-utils/issues" - }, "time": "2022-07-08T10:43:38+00:00" }, { @@ -92,13 +84,13 @@ "version": "v3.x-dev", "source": { "type": "git", - "url": "https://github.com/bagrinsergiu/brizy-content-placeholder.git", - "reference": "ea4b9b0c8e90828ea9bc67c3b0783fd1e256872a" + "url": "git@github.com:bagrinsergiu/brizy-content-placeholder.git", + "reference": "affd80ac76efac29ce0ee6baa0bfa7314f264612" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/bagrinsergiu/brizy-content-placeholder/zipball/ea4b9b0c8e90828ea9bc67c3b0783fd1e256872a", - "reference": "ea4b9b0c8e90828ea9bc67c3b0783fd1e256872a", + "url": "https://api.github.com/repos/bagrinsergiu/brizy-content-placeholder/zipball/affd80ac76efac29ce0ee6baa0bfa7314f264612", + "reference": "affd80ac76efac29ce0ee6baa0bfa7314f264612", "shasum": "" }, "require": { @@ -124,11 +116,7 @@ "content", "placeholders" ], - "support": { - "source": "https://github.com/bagrinsergiu/brizy-content-placeholder/tree/v3.0.4", - "issues": "https://github.com/bagrinsergiu/brizy-content-placeholder/issues" - }, - "time": "2024-09-03T13:09:04+00:00" + "time": "2024-09-17T12:13:44+00:00" }, { "name": "enshrined/svg-sanitize", @@ -274,12 +262,12 @@ "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "4d36e9c16f4820c2ed9360bc818982f3c02a08f5" + "reference": "0ed4c8949a32986043e977dbe14776c14d644c45" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/4d36e9c16f4820c2ed9360bc818982f3c02a08f5", - "reference": "4d36e9c16f4820c2ed9360bc818982f3c02a08f5", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/0ed4c8949a32986043e977dbe14776c14d644c45", + "reference": "0ed4c8949a32986043e977dbe14776c14d644c45", "shasum": "" }, "require": { @@ -322,7 +310,7 @@ "issues": "https://github.com/nikic/PHP-Parser/issues", "source": "https://github.com/nikic/PHP-Parser/tree/4.x" }, - "time": "2024-03-17T09:03:35+00:00" + "time": "2024-09-17T19:36:00+00:00" }, { "name": "phplrt/ast-contracts", @@ -1165,16 +1153,16 @@ "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "ec444d3f3f6505bb28d11afa41e75faadebc10a1" + "reference": "0f68c03565dcaaf25a890667542e8bd75fe7e5bb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/ec444d3f3f6505bb28d11afa41e75faadebc10a1", - "reference": "ec444d3f3f6505bb28d11afa41e75faadebc10a1", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/0f68c03565dcaaf25a890667542e8bd75fe7e5bb", + "reference": "0f68c03565dcaaf25a890667542e8bd75fe7e5bb", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "default-branch": true, "type": "library", @@ -1218,7 +1206,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php73/tree/v1.30.0" + "source": "https://github.com/symfony/polyfill-php73/tree/v1.31.0" }, "funding": [ { @@ -1234,7 +1222,7 @@ "type": "tidelift" } ], - "time": "2024-05-31T15:07:36+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "tburry/pquery", @@ -1432,5 +1420,5 @@ "php": ">=5.6" }, "platform-dev": [], - "plugin-api-version": "2.2.0" + "plugin-api-version": "2.6.0" } diff --git a/config.dev.php b/config.dev.php index 9afe66ecaf..0d236b3a60 100755 --- a/config.dev.php +++ b/config.dev.php @@ -25,7 +25,6 @@ class Brizy_Config const PLATFORM_EMAIL = "admin@admin.com"; const UPGRADE_TO_PRO_URL = "https://www.brizy.io/pricing/?utm_source=wp-menu&utm_campaign=gopro&utm_medium=wp-dash/"; - const EDITOR_TEMPLEATES_URL = "https://e-t-cloud.b-cdn.net/1.3.3-beta2/"; const EDITOR_NEW_TEMPLEATES_URL = "https://phplaravel-1109775-4184176.cloudwaysapps.com/"; const SUPPORT_URL = "https://support.brizy.io"; const ABOUT_URL = "https://brizy.io"; @@ -73,8 +72,6 @@ class Brizy_Config // this file will be stored in uploads/brizy/ const PROJECT_STLYES_FILE_PATH = DIRECTORY_SEPARATOR.'project'.DIRECTORY_SEPARATOR.'styles.css'; - const TEMPLATES_URL = 'https://template-mk.b-cdn.net'; - static public function getCompilerUrls() { $host = self::getEnvValue('COMPILER_HOST'); @@ -139,11 +136,6 @@ static public function getUpgradeUrl() return apply_filters('brizy_upgrade_to_pro_url', self::UPGRADE_TO_PRO_URL); } - static public function getEditorTemplatesUrl($directories) - { - return apply_filters('brizy_editor_config_templates_url', self::EDITOR_TEMPLEATES_URL.$directories); - } - static public function getEditorNewTemplatesUrl($directories) { return apply_filters('brizy_editor_config_templates_url', self::EDITOR_NEW_TEMPLEATES_URL.$directories); diff --git a/config.php b/config.php index 213771d639..b5903fa47d 100755 --- a/config.php +++ b/config.php @@ -26,7 +26,6 @@ class Brizy_Config const PLATFORM_EMAIL = "admin@admin.com"; const UPGRADE_TO_PRO_URL = "https://www.brizy.io/pricing/?utm_source=wp-menu&utm_campaign=gopro&utm_medium=wp-dash/"; - const EDITOR_TEMPLEATES_URL = "https://e-t-cloud.b-cdn.net/1.3.3-beta2/"; const SUPPORT_URL = "https://support.brizy.io"; const ABOUT_URL = "https://www.brizy.io"; const TERMS_OF_SERVICE_URL = "https://www.brizy.io/terms-and-conditions"; @@ -73,8 +72,6 @@ class Brizy_Config // this file will be stored in uploads/brizy/ const PROJECT_STLYES_FILE_PATH = '/project/styles.css'; - const TEMPLATES_URL = 'https://template-mk.b-cdn.net'; - static public function getCompilerUrls() { return new Brizy_Admin_UrlIterator( @@ -128,11 +125,6 @@ static public function getUpgradeUrl() return apply_filters('brizy_upgrade_to_pro_url', self::UPGRADE_TO_PRO_URL); } - static public function getEditorTemplatesUrl($directories) - { - return apply_filters('brizy_editor_config_templates_url', self::EDITOR_TEMPLEATES_URL.$directories); - } - static public function getTermsOfServiceUrl() { return apply_filters('brizy_config_terms_of_service_url', self::TERMS_OF_SERVICE_URL); diff --git a/editor/editor/editor.php b/editor/editor/editor.php index 205dce58fb..28160f63d1 100755 --- a/editor/editor/editor.php +++ b/editor/editor/editor.php @@ -411,10 +411,6 @@ private function getApiConfigFields($config, $context) 'fileUrl' => home_url('?'.Brizy_Editor::prefix('_attachment').'='), ], 'templates' => [ - 'kitsUrl' => Brizy_Config::getEditorTemplatesUrl('kits'), - 'layoutsUrl' => Brizy_Config::getEditorTemplatesUrl('layouts'), - 'popupsUrl' => Brizy_Config::getEditorTemplatesUrl('popups'), - 'storiesUrl' => Brizy_Config::getEditorTemplatesUrl('stories'), 'layoutsChunkUrl' => Brizy_Config::LAYOUTS_CHUNK_URL, 'layoutsPagesUrl' => Brizy_Config::LAYOUTS_PAGES_URL, 'layoutDataUrl' => Brizy_Config::LAYOUTS_PAGE_DATA_URL, @@ -426,7 +422,6 @@ private function getApiConfigFields($config, $context) 'storiesChunkUrl' => Brizy_Config::STORIES_CHUNK_URL, 'storiesPagesUrl' => Brizy_Config::STORIES_PAGES_URL, 'storiesDataUrl' => Brizy_Config::STORIES_DATA_URL, - 'templatesUrl' => Brizy_Config::TEMPLATES_URL, ], 'templatesImageUrl' => Brizy_Config::TEMPLATES_IMAGE_URL, ], diff --git a/public/editor-client/src/config.ts b/public/editor-client/src/config.ts index 242699e7b7..0005d6f4e0 100644 --- a/public/editor-client/src/config.ts +++ b/public/editor-client/src/config.ts @@ -9,10 +9,6 @@ import { throwOnNullish } from "./utils/throwOnNullish"; import { MValue } from "./utils/types"; interface DefaultTemplates { - kitsUrl: string; - popupsUrl: string; - storiesUrl: string; - layoutsUrl: string; layoutDataUrl: string; layoutsChunkUrl: string; layoutsPagesUrl: string; @@ -24,7 +20,6 @@ interface DefaultTemplates { storiesChunkUrl: string; storiesPagesUrl: string; storiesDataUrl: string; - templatesUrl: string; } interface Actions { @@ -83,6 +78,7 @@ interface API { fileUrl: string; templates: DefaultTemplates; openAIUrl?: string; + ekklesiaApiUrl?: string; iconsUrl?: string; iconUrl?: string; deleteIconUrl?: string; @@ -105,22 +101,6 @@ export interface Config { } const templatesReader = parseStrict, DefaultTemplates>({ - kitsUrl: pipe( - mPipe(Obj.readKey("kitsUrl"), Str.read), - throwOnNullish("Invalid API Config: kits") - ), - layoutsUrl: pipe( - mPipe(Obj.readKey("layoutsUrl"), Str.read), - throwOnNullish("Invalid API Config: layouts") - ), - popupsUrl: pipe( - mPipe(Obj.readKey("popupsUrl"), Str.read), - throwOnNullish("Invalid API Config: popups") - ), - storiesUrl: pipe( - mPipe(Obj.readKey("storiesUrl"), Str.read), - throwOnNullish("Invalid API Config: stories") - ), layoutDataUrl: pipe( mPipe(Obj.readKey("layoutDataUrl"), Str.read), throwOnNullish("Invalid API Config: layouts") @@ -164,10 +144,6 @@ const templatesReader = parseStrict, DefaultTemplates>({ storiesDataUrl: pipe( mPipe(Obj.readKey("storiesDataUrl"), Str.read), throwOnNullish("Invalid API Config: stories") - ), - templatesUrl: pipe( - mPipe(Obj.readKey("templatesUrl"), Str.read), - throwOnNullish("Invalid API Config: templates") ) }); @@ -236,7 +212,8 @@ const apiReader = parseStrict({ iconUrl: readIconUrl("iconUrl"), iconsUrl: readIconUrl("getIconsUrl"), uploadIconUrl: readIconUrl("uploadIconUrl"), - deleteIconUrl: readIconUrl("deleteIconUrl") + deleteIconUrl: readIconUrl("deleteIconUrl"), + ekklesiaApiUrl: optional(mPipe(Obj.readKey("ekklesiaApiUrl"), Str.read)) }); const actionsReader = parseStrict({ diff --git a/public/editor-client/src/customFile/addFile.ts b/public/editor-client/src/customFile/addFile.ts index a8ba1ff45a..2f98533f95 100644 --- a/public/editor-client/src/customFile/addFile.ts +++ b/public/editor-client/src/customFile/addFile.ts @@ -47,7 +47,7 @@ export const addFile: AddFileData = { .then((res) => res.blob()) .then((blob) => { const file = new File([blob], filename, { type: mimeType }); - validateByComponent(file, componentId) + validateByComponent(file, componentId, url) .then(() => handleGetAttachmentById(res, attachment)) .catch((e) => rej(e.message)); }); diff --git a/public/editor-client/src/customFile/lottieFile.ts b/public/editor-client/src/customFile/lottieFile.ts index 761491906e..334e7207a2 100644 --- a/public/editor-client/src/customFile/lottieFile.ts +++ b/public/editor-client/src/customFile/lottieFile.ts @@ -55,3 +55,5 @@ export const validateLottie = (file: File): Promise => fileReader.readAsText(file); }); + +export const isLottieFile = (file: string): boolean => /\.lottie$/i.test(file); diff --git a/public/editor-client/src/customFile/utils.ts b/public/editor-client/src/customFile/utils.ts index 95f74b40ea..2df9741244 100644 --- a/public/editor-client/src/customFile/utils.ts +++ b/public/editor-client/src/customFile/utils.ts @@ -2,15 +2,21 @@ import { Model } from "backbone"; import { getAttachmentById } from "../api"; import { UploadData } from "../types/File"; import { Response } from "../types/Response"; -import { validateLottie } from "./lottieFile"; +import { isLottieFile, validateLottie } from "./lottieFile"; export const validateByComponent = ( file: File, - componentId: string + componentId: string, + url: string ): Promise => { switch (componentId) { - case "Lottie": - return validateLottie(file); + case "Lottie": { + // we should validate only json lottie files + if (!isLottieFile(url)) { + return validateLottie(file); + } + return Promise.resolve(); + } default: return Promise.resolve(); } diff --git a/public/editor-client/src/ekklesia/index.ts b/public/editor-client/src/ekklesia/index.ts new file mode 100644 index 0000000000..64aa1f75d8 --- /dev/null +++ b/public/editor-client/src/ekklesia/index.ts @@ -0,0 +1,91 @@ +import { Config } from "config"; +import { ChoicesAsync, ChoicesSync } from "types/Choices"; +import { + EkklesiaExtra, + EkklesiaFieldMap, + EkklesiaFields, + EkklesiaKeys, + EkklesiaParams +} from "types/Ekklesia"; +import { Response } from "types/Response"; +import { t } from "utils/i18n"; +import { getFields } from "./utils"; + +export const getEkklesiaFields = (config: Config) => ({ + async handler( + res: Response, + rej: Response, + keys: EkklesiaParams, + extra?: EkklesiaExtra + ): Promise { + const { ekklesiaApiUrl } = config.api; + if (!ekklesiaApiUrl) { + if (process.env.NODE_ENV === "development") { + console.error("Missing Ekklesia api url!"); + } + res([{ value: "", title: t("None") }]); + return; + } + try { + const fields = await getFields(ekklesiaApiUrl, keys, extra); + res(fields); + } catch (error) { + if (process.env.NODE_ENV === "development") { + console.error("Failed to load ekklesia fields 2"); + } + rej(t("Failed to load ekklesia fields")); + } + } +}); + +export const updateEkklesiaFields = (config: Config) => ({ + async handler( + res: Response, + rej: Response, + keys: { + fields: Array; + }, + extra?: EkklesiaExtra + ): Promise { + const { ekklesiaApiUrl } = config.api; + + if (!ekklesiaApiUrl) { + if (process.env.NODE_ENV === "development") { + console.error("Missing Ekklesia api url!"); + } + rej(t("Missing Ekklesia api url!")); + return; + } + + const dataToChange: EkklesiaKeys = {}; + try { + for (const field of keys.fields) { + const choiches = await getFields( + ekklesiaApiUrl, + field.module, + extra + ); + + if (!choiches.length) continue; + + const updatedField = Object.keys(field.value).reduce((acc, key) => { + const value = field.value[key]; + const currentField = choiches.find( + (choice) => choice.value === value + ); + + if (!currentField) { + acc[key] = ""; + } + + return acc; + }, {} as EkklesiaKeys); + + Object.assign(dataToChange, updatedField); + } + res(Object.keys(dataToChange).length ? dataToChange : undefined); + } catch (error) { + rej(t("Failed to load ekklesia fields")); + } + } +}); diff --git a/public/editor-client/src/ekklesia/utils.ts b/public/editor-client/src/ekklesia/utils.ts new file mode 100644 index 0000000000..17cd0a7fc3 --- /dev/null +++ b/public/editor-client/src/ekklesia/utils.ts @@ -0,0 +1,65 @@ +import { Obj, Str } from "@brizy/readers"; +import { request } from "api/index"; +import { makeUrl } from "api/utils"; +import { ChoicesSync } from "types/Choices"; +import { + EkklesiaChoiceParamsWithSubKey, + EkklesiaExtra, + EkklesiaFields, + EkklesiaParams, + EkklesiaParentsChilds, + EkklesiaResponse +} from "types/Ekklesia"; +import { t } from "utils/i18n"; +import { Literal } from "utils/types"; + +export const requestFields = (url: string): Promise => { + return request(url).then((res) => res.json()); +}; + +export const fieldHaveParentsChildsKeys = ( + keys: Record | EkklesiaParentsChilds +): keys is EkklesiaParentsChilds => "childs" in keys && "parents" in keys; + +export const keysHaveSubkey = ( + keys: EkklesiaParams +): keys is EkklesiaChoiceParamsWithSubKey => "subKey" in keys; + +export const getOption = ( + obj: Record | undefined +): ChoicesSync => + Obj.isObject(obj) + ? [ + { title: t("None"), value: "" }, + ...Object.entries(obj).map(([key, value]) => { + return { + title: Str.read(value) ?? "", + value: key + }; + }) + ] + : []; + +export const getFields = async < + T extends keyof EkklesiaFields = keyof EkklesiaFields +>( + _url: string, + keys: EkklesiaParams, + extra?: EkklesiaExtra +): Promise => { + const { key } = keys; + + const url = makeUrl(_url, { module: key, ...extra }); + + const { data = {} } = await requestFields(url); + const field = data[key]; + + if (field && fieldHaveParentsChildsKeys(field)) { + if (keysHaveSubkey(keys)) { + return getOption(field[keys.subKey]); + } + return [{ value: "", title: t("None") }]; + } else { + return getOption(field); + } +}; diff --git a/public/editor-client/src/index.ts b/public/editor-client/src/index.ts index d424a90789..885c7afed2 100644 --- a/public/editor-client/src/index.ts +++ b/public/editor-client/src/index.ts @@ -1,4 +1,5 @@ import merge from "lodash/merge"; +import { getEkklesiaFields, updateEkklesiaFields } from "ekklesia/index"; import set from "lodash/set"; import { doAiRequest } from "./aiText"; import { autoSave } from "./autoSave"; @@ -67,6 +68,12 @@ const api = { searchCollectionItems, getCollectionItemsIds }, + modules: { + ekklesia: { + getEkklesiaFields: getEkklesiaFields(config), + updateEkklesiaFields: updateEkklesiaFields(config) + } + }, collectionTypes: { loadCollectionTypes }, diff --git a/public/editor-client/src/types/Ekklesia.ts b/public/editor-client/src/types/Ekklesia.ts new file mode 100644 index 0000000000..6ebc5fc731 --- /dev/null +++ b/public/editor-client/src/types/Ekklesia.ts @@ -0,0 +1,61 @@ +import { Literal } from "utils/types"; + +export interface EkklesiaResponse { + data: Partial; +} + +export interface EkklesiaFields { + groups: Record; + events: Record; + series: Record; + recentSermons: Record; + smallgroups: Record; + forms: Record; + sermon: Record; + event: Record; + smallgroup: Record; + eventsLvl: EkklesiaParentsChilds; + smallgroupsLvl: EkklesiaParentsChilds; +} + +export interface EkklesiaExtra { + find_group?: string; +} + +export interface EkklesiaParentsChilds { + parents: Record; + childs: Record; +} + +export interface EkklesiaChoiceParams< + T extends keyof EkklesiaFields = keyof EkklesiaFields +> { + key: T; +} + +export interface EkklesiaChoiceParamsWithSubKey< + T extends keyof EkklesiaFields = keyof EkklesiaFields +> extends EkklesiaChoiceParams { + subKey: keyof EkklesiaFields[T]; +} + +export type EkklesiaParams< + T extends keyof EkklesiaFields = keyof EkklesiaFields +> = EkklesiaFields[T] extends EkklesiaParentsChilds + ? EkklesiaChoiceParamsWithSubKey + : EkklesiaChoiceParams; + +export interface EkklesiaKeys { + [key: string]: string; +} + +export type EkklesiaFieldMap = { + [K in keyof EkklesiaFields]: EkklesiaModuleFields; +}; + +export interface EkklesiaModuleFields< + T extends keyof EkklesiaFields = keyof EkklesiaFields +> { + value: Record; + module: EkklesiaParams; +}