/** * WPML compatibility functions * * @global array $duplicated_posts Array to store the posts being duplicated. * * @package Yoast\WP\Duplicate_Post * @since 3.2 */ add_action( 'admin_init', 'duplicate_post_wpml_init' ); /** * Add handlers for WPML compatibility. */ function duplicate_post_wpml_init() { if ( defined( 'ICL_SITEPRESS_VERSION' ) ) { add_action( 'dp_duplicate_page', 'duplicate_post_wpml_copy_translations', 10, 3 ); add_action( 'dp_duplicate_post', 'duplicate_post_wpml_copy_translations', 10, 3 ); add_action( 'shutdown', 'duplicate_wpml_string_packages', 11 ); } } global $duplicated_posts; // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals -- Reason: Renaming a global variable is a BC break. $duplicated_posts = []; /** * Copy post translations. * * @global SitePress $sitepress Instance of the Main WPML class. * @global array $duplicated_posts Array of duplicated posts. * * @param int $post_id ID of the copy. * @param WP_Post $post Original post object. * @param string $status Status of the new post. */ function duplicate_post_wpml_copy_translations( $post_id, $post, $status = '' ) { global $sitepress; global $duplicated_posts; remove_action( 'dp_duplicate_page', 'duplicate_post_wpml_copy_translations', 10 ); remove_action( 'dp_duplicate_post', 'duplicate_post_wpml_copy_translations', 10 ); $current_language = $sitepress->get_current_language(); $trid = $sitepress->get_element_trid( $post->ID ); if ( ! empty( $trid ) ) { $translations = $sitepress->get_element_translations( $trid ); $new_trid = $sitepress->get_element_trid( $post_id ); foreach ( $translations as $code => $details ) { if ( $code !== $current_language ) { if ( $details->element_id ) { $translation = get_post( $details->element_id ); if ( ! $translation ) { continue; } $new_post_id = duplicate_post_create_duplicate( $translation, $status ); if ( ! is_wp_error( $new_post_id ) ) { $sitepress->set_element_language_details( $new_post_id, 'post_' . $translation->post_type, $new_trid, $code, $current_language ); } } } } // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals -- Reason: see above. $duplicated_posts[ $post->ID ] = $post_id; } } /** * Duplicate string packages. * * @global array() $duplicated_posts Array of duplicated posts. */ function duplicate_wpml_string_packages() { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals -- Reason: renaming the function would be a BC-break. global $duplicated_posts; foreach ( $duplicated_posts as $original_post_id => $duplicate_post_id ) { // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals -- Reason: using WPML native filter. $original_string_packages = apply_filters( 'wpml_st_get_post_string_packages', false, $original_post_id ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals -- Reason: using WPML native filter. $new_string_packages = apply_filters( 'wpml_st_get_post_string_packages', false, $duplicate_post_id ); if ( is_array( $original_string_packages ) ) { foreach ( $original_string_packages as $original_string_package ) { $translated_original_strings = $original_string_package->get_translated_strings( [] ); foreach ( $new_string_packages as $new_string_package ) { $cache = new WPML_WP_Cache( 'WPML_Package' ); $cache->flush_group_cache(); $new_strings = $new_string_package->get_package_strings(); foreach ( $new_strings as $new_string ) { if ( isset( $translated_original_strings[ $new_string->name ] ) ) { foreach ( $translated_original_strings[ $new_string->name ] as $language => $translated_string ) { do_action( // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals -- Reason: using WPML native filter. 'wpml_add_string_translation', $new_string->id, $language, $translated_string['value'], $translated_string['status'] ); } } } } } } } } scafold – Raqqa

モデル追加で空行追加

CREATE EXTENSION IF NOT EXISTS pgcrypto;

UPDATE public.portal_view_common
   SET action_xmlid = 'portal.auto.'|| id ||'.'|| replace(gen_random_uuid()::text,'-','')
 WHERE action_xmlid = '' OR action_xmlid IS NULL;

DROP FUNCTION IF EXISTS public.portal_scaffold_model(
  bigint, text[], boolean, boolean
);

CREATE OR REPLACE FUNCTION public.portal_scaffold_model(
  p_model_id     bigint,
  p_view_types   text[]    DEFAULT ARRAY['list','form','search'],
  p_make_tabs    boolean   DEFAULT true,   -- 互換のため残し(未使用)
  p_make_buttons boolean   DEFAULT true    -- 互換のため残し(未使用)
) RETURNS void AS $$
DECLARE
  v_model        text;
  v_model_table  text;
  v_vtype        text;
  v_view_id      bigint;
  v_common_id    bigint;
  v_action_xmlid text;

  has_permissions  boolean := (to_regclass('public.portal_view_permissions') IS NOT NULL);
  has_list_settings boolean := (to_regclass('public.portal_list_settings')   IS NOT NULL);
  has_form_settings boolean := (to_regclass('public.portal_form_settings')   IS NOT NULL);
  has_search_settings boolean := (to_regclass('public.portal_search_settings') IS NOT NULL);
BEGIN
  -- 対象モデル取得
  SELECT pm.model,
         COALESCE(pm.model_table, replace(pm.model,'.','_'))
    INTO v_model, v_model_table
  FROM public.portal_model pm
  WHERE pm.id = p_model_id;

  IF v_model IS NULL THEN
    RAISE EXCEPTION 'portal_model id % not found', p_model_id;
  END IF;

  -- モデル単位の排他
  PERFORM pg_advisory_xact_lock(hashtext(v_model));

  -- 要求された view_type を順次処理
  FOREACH v_vtype IN ARRAY p_view_types LOOP

    -- 既存ビュー探索
    SELECT pv.id, pv.common_id
      INTO v_view_id, v_common_id
    FROM public.portal_view pv
    WHERE pv.model = v_model
      AND pv.view_type = v_vtype
    LIMIT 1;

    IF v_view_id IS NULL THEN
      -- common を先に作る(action_xmlid は毎回ユニーク)
      v_action_xmlid :=
        'portal.auto.'|| p_model_id ||'.'|| replace(v_model,'.','_') ||'.'|| v_vtype
        ||'.'|| replace(gen_random_uuid()::text,'-','');

      INSERT INTO public.portal_view_common(action_xmlid, display_fields)
      VALUES (v_action_xmlid, '[]'::jsonb)
      RETURNING id INTO v_common_id;

      -- portal_view 作成(common_id を必ずセット)
      INSERT INTO public.portal_view(model, view_type, view_name, enabled, priority_num, common_id)
      VALUES (v_model, v_vtype, v_model || ' ' || v_vtype, true, 16, v_common_id)
      RETURNING id INTO v_view_id;

    ELSE
      -- 既存ビュー:common_id 欠落なら補完
      IF v_common_id IS NULL THEN
        v_action_xmlid :=
          'portal.auto.'|| p_model_id ||'.'|| replace(v_model,'.','_') ||'.'|| v_vtype
          ||'.'|| replace(gen_random_uuid()::text,'-','');

        INSERT INTO public.portal_view_common(action_xmlid, display_fields)
        VALUES (v_action_xmlid, '[]'::jsonb)
        RETURNING id INTO v_common_id;

        UPDATE public.portal_view
           SET common_id = v_common_id
         WHERE id = v_view_id;
      END IF;
    END IF;

    -- 付随 1:1(存在するテーブルのみ挿入)
    IF has_permissions THEN
      INSERT INTO public.portal_view_permissions(
        view_id, can_create, can_edit, can_delete, inline_edit, mass_edit, show_invisible
      ) VALUES (v_view_id, true, true, false, false, false, false)
      ON CONFLICT (view_id) DO NOTHING;
    END IF;

    IF v_vtype = 'list' AND has_list_settings THEN
      INSERT INTO public.portal_list_settings(view_id, inline_edit)
      VALUES (v_view_id, false)
      ON CONFLICT (view_id) DO NOTHING;
    ELSIF v_vtype = 'form' AND has_form_settings THEN
      INSERT INTO public.portal_form_settings(view_id, show_header, show_footer)
      VALUES (v_view_id, true, true)
      ON CONFLICT (view_id) DO NOTHING;
    ELSIF v_vtype = 'search' AND has_search_settings THEN
      INSERT INTO public.portal_search_settings(view_id, search_fields, filters, group_by_filters)
      VALUES (v_view_id, NULL, NULL, NULL)
      ON CONFLICT (view_id) DO NOTHING;
    END IF;

    -- クリア
    v_view_id := NULL;
    v_common_id := NULL;
    v_action_xmlid := NULL;
  END LOOP;
END;
$$ LANGUAGE plpgsql;

Comments

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です