HEX
Server: Apache
System: Linux scp1.abinfocom.com 5.4.0-216-generic #236-Ubuntu SMP Fri Apr 11 19:53:21 UTC 2025 x86_64
User: confeduphaar (1010)
PHP: 8.1.33
Disabled: exec,passthru,shell_exec,system
Upload Files
File: /home/confeduphaar/public_html/wp-content/plugins/essential-blocks/src/blocks/taxonomy/src/edit.js
/**
 * WordPress dependencies
 */
import { __ } from "@wordpress/i18n";
import { Fragment, useEffect, memo, useState } from "@wordpress/element";
import { useEntityRecords, store as coreStore } from "@wordpress/core-data";
import { select, useSelect, withSelect } from "@wordpress/data";
import { compose } from "@wordpress/compose";
import apiFetch from "@wordpress/api-fetch";

/**
 * Internal depencencies
 */
import Style from "./style";
import Inspector from "./inspector";
import defaultAttributes from "./attributes";
import { ReactComponent as TaxonomyIcon } from "./icon.svg";
import { ebLoader, renderCategoryName } from "./helpers";

/**
 * External depencencies
 */
import {
    DynamicInputValueHandler,
    BlockProps,
    withBlockContext,
    EBDisplayIcon,
    NoticeComponent,
} from "@essential-blocks/controls";

function Edit(props) {
    const { attributes, setAttributes, isSelected, selectPostType, context } =
        props;

    const {
        blockId,
        classHook,
        selectedTaxonomy,
        showHierarchy,
        showPostCounts,
        displayStyle,
        prefixType,
        prefixText,
        prefixIcon,
        suffixType,
        suffixIcon,
        suffixText,
        separator,
        showSeparator,
        taxonomyLimit,
        taxonomiesQuery,
        source,
        currentPostType,
        currentPostId,
    } = attributes;

    // you must declare this variable
    const enhancedProps = {
        ...props,
        blockPrefix: "eb-taxonomy",
        style: <Style {...props} />,
    };

    // this useEffect is for creating a unique id for each block's unique className by a random unique number
    useEffect(() => {
        if (selectPostType) {
            setAttributes({
                currentPostType: selectPostType,
            });
        }
    }, []);

    const postType = select("core/editor").getCurrentPostType();

    // Get post data from Loop Builder context
    const loopPostId = context?.["essential-blocks/postId"];
    const loopPostType = context?.["essential-blocks/postType"];

    // Check if block is inside Loop Builder context
    // We need to check multiple conditions because context might be available at different times
    const isInLoopBuilder = Boolean(
        context &&
            // Primary check: explicit isLoopBuilder flag
            (context["essential-blocks/isLoopBuilder"] === true ||
                // Secondary check: presence of loop context values (even if null initially)
                (context.hasOwnProperty("essential-blocks/postId") &&
                    context.hasOwnProperty("essential-blocks/postType"))),
    );

    // Use loop context values when in Loop Builder, otherwise use current values
    const effectivePostType = isInLoopBuilder ? loopPostType : postType;
    const effectivePostId = isInLoopBuilder ? loopPostId : currentPostId;

    // State for Loop Builder taxonomy data
    const [loopBuilderTaxonomyData, setLoopBuilderTaxonomyData] =
        useState(null);
    const [isLoadingLoopData, setIsLoadingLoopData] = useState(false);

    // Effect to handle Loop Builder context initialization
    useEffect(() => {
        if (isInLoopBuilder) {
            // Set source to current-post and update context values
            setAttributes({
                source: "current-post",
                currentPostId: loopPostId || 0,
                currentPostType: loopPostType || "post",
            });
        }
    }, [isInLoopBuilder, loopPostId, loopPostType]);

    // Effect to fetch taxonomy data for Loop Builder context
    useEffect(() => {
        if (isInLoopBuilder && effectivePostId && selectedTaxonomy) {
            setIsLoadingLoopData(true);

            // Fetch post data to get taxonomy terms
            apiFetch({
                path: `/wp/v2/${effectivePostType}s/${effectivePostId}?_embed`,
            })
                .then((postData) => {
                    // Extract taxonomy terms from the post data
                    const taxonomyTerms = [];

                    if (
                        postData &&
                        postData._embedded &&
                        postData._embedded["wp:term"]
                    ) {
                        // Find terms for the selected taxonomy
                        const termArrays = postData._embedded["wp:term"];
                        termArrays.forEach((termArray) => {
                            termArray.forEach((term) => {
                                if (term.taxonomy === selectedTaxonomy) {
                                    taxonomyTerms.push({
                                        id: term.id,
                                        name: term.name,
                                        link: term.link,
                                        count: term.count || 0,
                                        parent: term.parent || 0,
                                    });
                                }
                            });
                        });
                    }

                    setLoopBuilderTaxonomyData(taxonomyTerms);
                    setIsLoadingLoopData(false);
                })
                .catch((error) => {
                    console.error(
                        "Failed to fetch taxonomy data for Loop Builder:",
                        error,
                    );
                    setLoopBuilderTaxonomyData([]);
                    setIsLoadingLoopData(false);
                });
        } else if (!isInLoopBuilder) {
            // Clear Loop Builder data when not in Loop Builder context
            setLoopBuilderTaxonomyData(null);
            setIsLoadingLoopData(false);
        }
    }, [isInLoopBuilder, effectivePostId, effectivePostType, selectedTaxonomy]);

    useEffect(() => {
        if (taxonomyLimit == undefined) {
            setAttributes({ taxonomyLimit: 0 });
        }
    }, [taxonomyLimit]);

    // on source change
    useEffect(() => {
        if (isInLoopBuilder && source === "current-post") {
            setAttributes({
                taxonomiesQuery: {
                    ...taxonomiesQuery,
                    type: effectivePostType,
                },
            });
        } else if (!isInLoopBuilder && source === "current-post") {
            if (postType === "templately_library") {
                let type = "post";
                const templateType =
                    select("core/editor").getEditedPostAttribute(
                        "templately_type",
                    );
                if (templateType) {
                    if (
                        ["product_archive", "product_single"].includes(
                            templateType,
                        )
                    ) {
                        type = "product";
                    }
                    if (
                        ["course_archive", "course_single"].includes(
                            templateType,
                        )
                    ) {
                        type = "sfwd-courses";
                    }
                }
                setAttributes({
                    taxonomiesQuery: { ...taxonomiesQuery, type },
                });
            } else if (postType === "wp_template") {
                const slugArray = select("core/editor")
                    .getEditedPostAttribute("slug")
                    .split("-");
                let type = "post";
                if (slugArray.length > 1) {
                    type = slugArray[1];
                }
                if (slugArray.length === 1 && slugArray[0] === "page") {
                    type = "page";
                }
                setAttributes({
                    taxonomiesQuery: { ...taxonomiesQuery, type },
                });
            } else {
                setAttributes({
                    taxonomiesQuery: {
                        ...taxonomiesQuery,
                        type: selectPostType,
                    },
                });
            }
        } else {
            let newQuery = { ...taxonomiesQuery };
            if (newQuery.hasOwnProperty("type")) {
                delete newQuery.type;
            }
            setAttributes({ taxonomiesQuery: newQuery });
        }
    }, [source]);

    // on taxonomiesQuery change
    const { taxonomies, hasResolved } = useSelect(
        (select) => {
            return {
                taxonomies: select(coreStore).getTaxonomies(taxonomiesQuery),
                hasResolved: select(coreStore).hasFinishedResolution(
                    "getTaxonomies",
                    [taxonomiesQuery],
                ),
            };
        },
        [taxonomiesQuery],
    );

    useEffect(() => {
        if (hasResolved) {
            if (!selectedTaxonomy && taxonomies && taxonomies.length) {
                setAttributes({ selectedTaxonomy: taxonomies[0].slug });
            } else {
                if (taxonomies && taxonomies.length) {
                    const slugs = taxonomies.map((each) => each.slug);
                    if (!slugs.includes(selectedTaxonomy)) {
                        setAttributes({ selectedTaxonomy: slugs[0] });
                    }
                } else {
                    setAttributes({ selectedTaxonomy: "" });
                }
            }
        }
    }, [taxonomies, hasResolved]);
    const query = { per_page: taxonomyLimit == 0 ? -1 : taxonomyLimit }
    const { records: categories, isResolving } = useEntityRecords(
        "taxonomy",
        selectedTaxonomy,
        query,
    );

    const getCategoriesList = (parentId) => {
        if (!categories?.length) {
            return [];
        }
        if (parentId === null) {
            return categories;
        }
        return categories.filter(({ parent }) => parent === parentId);
    };

    const renderCategoryList = () => {
        let categoriesList = [];
        if (source === 'current-post') {
            let name = 'Category'
            if (selectedTaxonomy && taxonomies) {
                const tax = taxonomies.find(each => each.slug === selectedTaxonomy);
                if (tax) {
                    name = tax.name
                }
            }
            categoriesList = [{
                id: 0, link: '#', count: 5, name
            }]
        } else {
            const parentId = showHierarchy ? 0 : null;
            categoriesList = getCategoriesList(parentId);
        }
        return categoriesList.map((category, index) => renderCategoryListItem(category));
    };

    const renderCategoryListItem = (category) => {
        const childCategories = getCategoriesList(category.id);
        const { id, link, count, name } = category;
        return (
            <Fragment key={id}>
                <span className={`eb-tax-item eb-tax-item-${id}`}>
                    <a href={link} target="_blank" rel="noreferrer noopener">
                        {renderCategoryName(name)}
                    </a>
                    {showPostCounts && ` (${count})`}
                    {showHierarchy && childCategories.length && (
                        <ul className="children">
                            {childCategories.map((childCategory) =>
                                renderCategoryListItem(childCategory)
                            )}
                        </ul>
                    )}
                </span>
                {showSeparator && separator && (
                    <span className="eb-tax-separator">{separator}</span>
                )}
            </Fragment>
        );
    };
    const taxonomyNotice = ebLoader();

    return (
        <>
            {isSelected && (
                <Inspector
                    attributes={attributes}
                    setAttributes={setAttributes}
                    taxonomies={taxonomies}
                    context={context}
                />
            )}

            <BlockProps.Edit {...enhancedProps}>
                <div
                    className={`eb-parent-wrapper eb-parent-${blockId} ${classHook}`}
                >
                    {!hasResolved && (
                        <NoticeComponent
                            Icon={TaxonomyIcon}
                            title={__("Taxonomy", "essential-blocks")}
                            description={taxonomyNotice}
                        />
                    )}

                    {hasResolved && !taxonomies && (
                        <NoticeComponent
                            Icon={TaxonomyIcon}
                            title={__("Taxonomy", "essential-blocks")}
                            description={`No taxonomies found for this post`}
                        />
                    )}

                    {hasResolved && taxonomies && (
                        <>
                            {Array.isArray(categories) &&
                                categories.length == 0 &&
                                eb_conditional_localize?.editor_type !==
                                    "edit-site" && (
                                    <NoticeComponent
                                        Icon={TaxonomyIcon}
                                        title={__(
                                            "Taxonomy",
                                            "essential-blocks",
                                        )}
                                        description={`Not found any data.`}
                                    />
                                )}
                            <div
                                className={`eb-taxonomies-wrapper ${blockId} ${displayStyle}`}
                                data-id={blockId}
                            >
                                {prefixType !== "none" && (
                                    <div className="prefix-wrap">
                                        {prefixType === "text" &&
                                            prefixText && (
                                                <DynamicInputValueHandler
                                                    value={prefixText}
                                                    tagName="span"
                                                    className="eb-taxonomy-prefix-text"
                                                    onChange={(prefixText) =>
                                                        setAttributes({
                                                            prefixText,
                                                        })
                                                    }
                                                    readOnly={true}
                                                />
                                            )}

                                        {prefixType === "icon" &&
                                            prefixIcon && (
                                                <EBDisplayIcon
                                                    icon={prefixIcon}
                                                    className={`eb-taxonomy-prefix-icon`}
                                                />
                                            )}
                                    </div>
                                )}

                                <div className="eb-tax-wrap">
                                    {renderCategoryList()}
                                </div>

                                {suffixType !== "none" && (
                                    <div className="suffix-wrap">
                                        {suffixType === "text" &&
                                            suffixText && (
                                                <DynamicInputValueHandler
                                                    value={suffixText}
                                                    placeholder="placeholder text"
                                                    tagName="span"
                                                    className="eb-taxonomy-suffix-text"
                                                    onChange={(suffixText) =>
                                                        setAttributes({
                                                            suffixText,
                                                        })
                                                    }
                                                    readOnly={true}
                                                />
                                            )}

                                        {suffixType === "icon" &&
                                            suffixIcon && (
                                                <EBDisplayIcon
                                                    icon={suffixIcon}
                                                    className={`eb-taxonomy-suffix-icon`}
                                                />
                                            )}
                                    </div>
                                )}
                            </div>
                        </>
                    )}
                </div>
            </BlockProps.Edit>
        </>
    );
}
export default memo(
    compose([
        withSelect((select, ownProps) => {
            const selectPostType = select("core/editor")
                ? select("core/editor").getCurrentPostType()
                : "";
            return {
                selectPostType: selectPostType,
            };
        }),
        withBlockContext(defaultAttributes),
    ])(Edit),
);