| @@ -3,9 +3,10 @@ | ||
| 3 | 3 | class WP_Attachments |
| 4 | 4 | { |
| 5 | 5 | private $actions = array( |
| 6 | 6 | 'add_meta_boxes', 'admin_enqueue_scripts', |
| 7 | - 'wp_ajax_wpa_realign', 'wp_ajax_wpa_attach_media' // renamed from ij_ | |
| 7 | + 'wp_ajax_wpa_realign', 'wp_ajax_wpa_attach_media', // renamed from ij_ | |
| 8 | + 'wp_ajax_wpa_unattach_media', 'wp_ajax_wpa_delete_media' | |
| 8 | 9 | ); |
| 9 | 10 | |
| 10 | 11 | private static $instance; |
| 11 | 12 | |
| @@ -84,9 +85,9 @@ | ||
| 84 | 85 | wp_enqueue_script( |
| 85 | 86 | 'wp-attachments', |
| 86 | 87 | plugin_dir_url(__FILE__) . 'scripts/metabox.js', |
| 87 | 88 | array('jquery-ui-sortable'), |
| 88 | - '6.0', | |
| 89 | + WPATT_VERSION, | |
| 89 | 90 | true |
| 90 | 91 | ); |
| 91 | 92 | |
| 92 | 93 | wp_localize_script('wp-attachments', 'WP_Attachments_Vars', array( |
| @@ -108,8 +109,12 @@ | ||
| 108 | 109 | 'previewLabel' => __('Preview %s', 'wp-attachments'), |
| 109 | 110 | 'previewFallback' => __('File Preview', 'wp-attachments'), |
| 110 | 111 | 'previewUnavailable' => __('Preview not available for this file type.', 'wp-attachments'), |
| 111 | 112 | 'downloadFile' => __('Download file', 'wp-attachments'), |
| 113 | + 'fileUnattached' => __('File unattached.', 'wp-attachments'), | |
| 114 | + 'fileDeleted' => __('File deleted.', 'wp-attachments'), | |
| 115 | + 'actionFailed' => __('The file could not be changed.', 'wp-attachments'), | |
| 116 | + 'requestFailed' => __('The request failed. Please try again.', 'wp-attachments'), | |
| 112 | 117 | 'postID' => get_the_ID(), // Use get_the_ID() instead of $_GET |
| 113 | 118 | 'ajaxurl' => admin_url('admin-ajax.php'), |
| 114 | 119 | 'nonce' => wp_create_nonce('wpa-attachments-nonce') |
| 115 | 120 | )); |
| @@ -115,9 +120,9 @@ | ||
| 115 | 120 | )); |
| 116 | 121 | |
| 117 | 122 | // Inline-only stylesheet: registering a handle keeps the CSS inside the |
| 118 | 123 | // normal dependency pipeline instead of echoing it mid-request. |
| 119 | - wp_register_style('wpa-metabox', false, array(), '6.0'); | |
| 124 | + wp_register_style('wpa-metabox', false, array(), WPATT_VERSION); | |
| 120 | 125 | wp_enqueue_style('wpa-metabox'); |
| 121 | 126 | wp_add_inline_style('wpa-metabox', $this->getStyles()); |
| 122 | 127 | } |
| 123 | 128 | |
| @@ -190,10 +195,14 @@ | ||
| 190 | 195 | padding: 10px 12px; |
| 191 | 196 | background: var(--wpa-surface); |
| 192 | 197 | border: 1px solid var(--wpa-border); |
| 193 | 198 | border-radius: var(--wpa-radius); |
| 194 | - transition: border-color .15s ease, box-shadow .15s ease; | |
| 199 | + transition: border-color .15s ease, box-shadow .15s ease, opacity .2s ease; | |
| 195 | 200 | } |
| 201 | +.wpa-attachments-wrapper .wpa-attachment-item.is-busy { | |
| 202 | + opacity: .5; | |
| 203 | + pointer-events: none; | |
| 204 | +} | |
| 196 | 205 | .wpa-attachments-wrapper .wpa-attachment-item:hover { |
| 197 | 206 | border-color: var(--wpa-border-strong); |
| 198 | 207 | box-shadow: 0 1px 2px rgba(0, 0, 0, .06); |
| 199 | 208 | } |
| @@ -617,124 +626,8 @@ | ||
| 617 | 626 | ); |
| 618 | 627 | } |
| 619 | 628 | |
| 620 | 629 | /** |
| 621 | - * Reduce a MIME type to one of the icon families below. | |
| 622 | - */ | |
| 623 | - private function getFileType($mime_type) | |
| 624 | - { | |
| 625 | - $mime_type = strtolower((string) $mime_type); | |
| 626 | - | |
| 627 | - // Checked in order: the first prefix that matches wins, so the more | |
| 628 | - // specific entries (text/csv) come before the broad ones (text/). | |
| 629 | - $prefixes = array( | |
| 630 | - 'image/' => 'image', | |
| 631 | - 'video/' => 'video', | |
| 632 | - 'audio/' => 'audio', | |
| 633 | - 'text/csv' => 'sheet', | |
| 634 | - 'text/html' => 'code', | |
| 635 | - 'text/' => 'text', | |
| 636 | - ); | |
| 637 | - foreach ($prefixes as $prefix => $type) { | |
| 638 | - if (strpos($mime_type, $prefix) === 0) { | |
| 639 | - return $type; | |
| 640 | - } | |
| 641 | - } | |
| 642 | - | |
| 643 | - $needles = array( | |
| 644 | - 'pdf' => 'pdf', | |
| 645 | - 'wordprocessing' => 'doc', | |
| 646 | - 'msword' => 'doc', | |
| 647 | - 'opendocument.text' => 'doc', | |
| 648 | - 'rtf' => 'doc', | |
| 649 | - 'spreadsheet' => 'sheet', | |
| 650 | - 'ms-excel' => 'sheet', | |
| 651 | - 'presentation' => 'slides', | |
| 652 | - 'ms-powerpoint' => 'slides', | |
| 653 | - 'zip' => 'archive', | |
| 654 | - 'compressed' => 'archive', | |
| 655 | - 'tar' => 'archive', | |
| 656 | - 'gzip' => 'archive', | |
| 657 | - 'json' => 'code', | |
| 658 | - 'xml' => 'code', | |
| 659 | - 'javascript' => 'code', | |
| 660 | - ); | |
| 661 | - foreach ($needles as $needle => $type) { | |
| 662 | - if (strpos($mime_type, $needle) !== false) { | |
| 663 | - return $type; | |
| 664 | - } | |
| 665 | - } | |
| 666 | - | |
| 667 | - return 'default'; | |
| 668 | - } | |
| 669 | - | |
| 670 | - /** | |
| 671 | - * Inline SVG icon for a file family. | |
| 672 | - * | |
| 673 | - * Inline rather than a font or sprite: crisp at any pixel density, colour | |
| 674 | - * comes from the tile via currentColor, and it costs no extra request. | |
| 675 | - */ | |
| 676 | - private function getFileIconSvg($type) | |
| 677 | - { | |
| 678 | - $open = '<svg class="wpa-file-icon" viewBox="0 0 24 24" fill="none" aria-hidden="true" focusable="false">'; | |
| 679 | - $close = '</svg>'; | |
| 680 | - | |
| 681 | - // Sheet of paper with a folded corner, shared by the document families. | |
| 682 | - $page = '<path d="M14 2.75H7A2.25 2.25 0 0 0 4.75 5v14A2.25 2.25 0 0 0 7 21.25h10A2.25 2.25 0 0 0 19.25 19V8L14 2.75Z" fill="currentColor" fill-opacity=".13"/>' | |
| 683 | - . '<path d="M14 2.75H7A2.25 2.25 0 0 0 4.75 5v14A2.25 2.25 0 0 0 7 21.25h10A2.25 2.25 0 0 0 19.25 19V8L14 2.75Z" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round"/>' | |
| 684 | - . '<path d="M13.75 3v4.25H18" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round"/>'; | |
| 685 | - | |
| 686 | - // Rounded frame shared by the media families. | |
| 687 | - $frame = '<rect x="3.75" y="4.75" width="16.5" height="14.5" rx="2.25" fill="currentColor" fill-opacity=".13"/>' | |
| 688 | - . '<rect x="3.75" y="4.75" width="16.5" height="14.5" rx="2.25" stroke="currentColor" stroke-width="1.5"/>'; | |
| 689 | - | |
| 690 | - $glyphs = array( | |
| 691 | - 'pdf' => $page | |
| 692 | - . '<path d="M8 12.5h8M8 15.5h8M8 18.5h5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>', | |
| 693 | - | |
| 694 | - 'doc' => $page | |
| 695 | - . '<path d="M8 12.5h8M8 15.5h8M8 18.5h5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>', | |
| 696 | - | |
| 697 | - 'text' => $page | |
| 698 | - . '<path d="M8 12.5h8M8 15.5h8M8 18.5h5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>', | |
| 699 | - | |
| 700 | - 'sheet' => $page | |
| 701 | - . '<rect x="7.25" y="12.25" width="9.5" height="6.5" rx="1" stroke="currentColor" stroke-width="1.5"/>' | |
| 702 | - . '<path d="M12 12.25v6.5M7.25 15.5h9.5" stroke="currentColor" stroke-width="1.5"/>', | |
| 703 | - | |
| 704 | - 'slides' => $page | |
| 705 | - . '<rect x="7.25" y="12.25" width="9.5" height="6.5" rx="1" stroke="currentColor" stroke-width="1.5"/>' | |
| 706 | - . '<path d="M9.5 16.5l2-2 1.75 1.75 1.25-1.25" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>', | |
| 707 | - | |
| 708 | - 'code' => $page | |
| 709 | - . '<path d="M10.25 12.75 7.75 15.5l2.5 2.75M13.75 12.75l2.5 2.75-2.5 2.75" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>', | |
| 710 | - | |
| 711 | - 'image' => $frame | |
| 712 | - . '<circle cx="8.75" cy="10" r="1.5" fill="currentColor"/>' | |
| 713 | - . '<path d="M4.75 17.5 9.5 12.75l3.25 3.25 2.25-1.75 4.25 3.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>', | |
| 714 | - | |
| 715 | - 'video' => $frame | |
| 716 | - . '<path d="M10.25 9.25v5.5l5-2.75-5-2.75Z" fill="currentColor"/>', | |
| 717 | - | |
| 718 | - 'audio' => '<path d="M9.5 16.5V6.75l8.75-1.75V14.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>' | |
| 719 | - . '<ellipse cx="7.25" cy="16.75" rx="2.75" ry="2.25" fill="currentColor"/>' | |
| 720 | - . '<ellipse cx="16" cy="14.75" rx="2.75" ry="2.25" fill="currentColor"/>', | |
| 721 | - | |
| 722 | - 'archive' => '<path d="M4.75 7.75h14.5V19A2.25 2.25 0 0 1 17 21.25H7A2.25 2.25 0 0 1 4.75 19V7.75Z" fill="currentColor" fill-opacity=".13"/>' | |
| 723 | - . '<rect x="3.75" y="3.75" width="16.5" height="4" rx="1.25" stroke="currentColor" stroke-width="1.5"/>' | |
| 724 | - . '<path d="M5 7.75V19A2.25 2.25 0 0 0 7.25 21.25h9.5A2.25 2.25 0 0 0 19 19V7.75" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round"/>' | |
| 725 | - . '<path d="M10.25 11.5h3.5M10.25 14.5h3.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>', | |
| 726 | - | |
| 727 | - 'default' => $page | |
| 728 | - . '<path d="M8 13.5h8M8 16.5h5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>', | |
| 729 | - ); | |
| 730 | - | |
| 731 | - $glyph = isset($glyphs[$type]) ? $glyphs[$type] : $glyphs['default']; | |
| 732 | - | |
| 733 | - return $open . $glyph . $close; | |
| 734 | - } | |
| 735 | - | |
| 736 | - /** | |
| 737 | 630 | * Row-action icons, drawn to stay legible at 18px. |
| 738 | 631 | */ |
| 739 | 632 | private function getActionIcon($name) |
| 740 | 633 | { |
| @@ -815,9 +708,9 @@ | ||
| 815 | 708 | . '<svg viewBox="0 0 24 24" fill="none" focusable="false"><circle cx="12" cy="12" r="9" fill="rgba(0,0,0,.55)"/><path d="M10 8.5v7l5.5-3.5-5.5-3.5Z" fill="#fff"/></svg>' |
| 816 | 709 | . '</span>'; |
| 817 | 710 | } |
| 818 | 711 | } else { |
| 819 | - $inner = $this->getFileIconSvg($this->getFileType($mime_type)); | |
| 712 | + $inner = wpatt_get_file_icon_svg(wpatt_get_file_type($mime_type)); | |
| 820 | 713 | } |
| 821 | 714 | |
| 822 | 715 | $previewable = $is_image |
| 823 | 716 | || $is_video |
| @@ -862,12 +755,12 @@ | ||
| 862 | 755 | $size = 0; |
| 863 | 756 | |
| 864 | 757 | foreach ((array) $attachments as $attachment) { |
| 865 | 758 | $count++; |
| 866 | - $id = is_object($attachment) ? $attachment->ID : (int) $attachment; | |
| 867 | - $path = get_attached_file($id); | |
| 868 | - if ($path && file_exists($path)) { | |
| 869 | - $size += filesize($path); | |
| 759 | + $id = is_object($attachment) ? $attachment->ID : (int) $attachment; | |
| 760 | + $bytes = wpatt_get_attachment_filesize($id); | |
| 761 | + if (false !== $bytes) { | |
| 762 | + $size += $bytes; | |
| 870 | 763 | } |
| 871 | 764 | } |
| 872 | 765 | |
| 873 | 766 | return array('count' => $count, 'size' => $size); |
| @@ -932,19 +825,10 @@ | ||
| 932 | 825 | )); |
| 933 | 826 | |
| 934 | 827 | $stats = $this->getStats($attachments->posts); |
| 935 | 828 | |
| 936 | - // Get default ON/OFF for this post type | |
| 937 | - $default_on = get_option('wpatt_enable_display_' . $post->post_type, '1'); | |
| 938 | - $is_off = get_post_meta($post->ID, 'wpa_off', true); | |
| 939 | - // If meta not set, use default | |
| 940 | - if ( $is_off == 1 ) { | |
| 941 | - // Disabled by user | |
| 942 | - } else if (in_array($post->post_status, array('auto-draft', 'draft', 'new'))) { | |
| 943 | - $is_off = ($default_on === '1') ? '' : '1'; | |
| 944 | - } else { | |
| 945 | - $is_off = ($default_on === '1') ? '' : '1'; | |
| 946 | - } | |
| 829 | + $is_off = !wpatt_is_display_enabled($post); | |
| 830 | + $frontend_on = wpatt_is_frontend_enabled($post->post_type); | |
| 947 | 831 | ?> |
| 948 | 832 | |
| 949 | 833 | <div class="wpa-attachments-wrapper"> |
| 950 | 834 | <div class="wpa-attachments-stats" id="wpa-attachments-stats"> |
| @@ -974,12 +858,16 @@ | ||
| 974 | 858 | ?></p> |
| 975 | 859 | <div id="wpa-reorder-status" class="screen-reader-text" role="status" aria-live="polite"></div> |
| 976 | 860 | |
| 977 | 861 | <div class="wpa-attachments-footer"> |
| 978 | - <div class="wpa-toggle-wrapper"> | |
| 979 | - <input type="checkbox" id="wpa_off_n" name="wpa_off" <?php checked(!$is_off); ?> /> | |
| 980 | - <label for="wpa_off_n"><?php esc_html_e('Display attachments in frontend', 'wp-attachments'); ?></label> | |
| 981 | - </div> | |
| 862 | + <?php if ($frontend_on) : ?> | |
| 863 | + <div class="wpa-toggle-wrapper"> | |
| 864 | + <input type="checkbox" id="wpa_off_n" name="wpa_off" <?php checked(!$is_off); ?> /> | |
| 865 | + <label for="wpa_off_n"><?php esc_html_e('Display attachments in frontend', 'wp-attachments'); ?></label> | |
| 866 | + </div> | |
| 867 | + <?php else : ?> | |
| 868 | + <p class="description"><?php esc_html_e('The frontend list is disabled for this post type in the WP Attachments settings.', 'wp-attachments'); ?></p> | |
| 869 | + <?php endif; ?> | |
| 982 | 870 | <?php if (current_user_can('upload_files')) : ?> |
| 983 | 871 | <div class="wpa-attachments-footer-buttons"> |
| 984 | 872 | <?php // type="button": inside the edit form a bare <button> defaults to submit. ?> |
| 985 | 873 | <button type="button" class="button button-primary add_media wpa_attach_file"> |
| @@ -1111,9 +999,85 @@ | ||
| 1111 | 999 | 'skipped' => $skipped, |
| 1112 | 1000 | )); |
| 1113 | 1001 | } |
| 1114 | 1002 | |
| 1003 | + // AJAX: unattach a file from the post being edited. | |
| 1004 | + public function wp_ajax_wpa_unattach_media() | |
| 1005 | + { | |
| 1006 | + $this->handleRowAction('unattach'); | |
| 1007 | + } | |
| 1008 | + | |
| 1009 | + // AJAX: permanently delete a file of the post being edited. | |
| 1010 | + public function wp_ajax_wpa_delete_media() | |
| 1011 | + { | |
| 1012 | + $this->handleRowAction('delete'); | |
| 1013 | + } | |
| 1014 | + | |
| 1115 | 1015 | /** |
| 1016 | + * Shared handler for the unattach and delete row actions. | |
| 1017 | + * | |
| 1018 | + * One file per request, on purpose. It must be attached to the given | |
| 1019 | + * post and is checked on its own: a nonce plus the right to edit the | |
| 1020 | + * post must not be enough to unattach or delete somebody else's file. | |
| 1021 | + * | |
| 1022 | + * @param string $action 'unattach' or 'delete'. | |
| 1023 | + */ | |
| 1024 | + private function handleRowAction($action) | |
| 1025 | + { | |
| 1026 | + check_ajax_referer('wpa-attachments-nonce', 'nonce'); | |
| 1027 | + | |
| 1028 | + $post_id = isset($_POST['post_id']) ? absint($_POST['post_id']) : 0; | |
| 1029 | + if (!$post_id || !current_user_can('edit_post', $post_id)) { | |
| 1030 | + wp_send_json_error(__('Permission denied', 'wp-attachments'), 403); | |
| 1031 | + } | |
| 1032 | + | |
| 1033 | + $id = isset($_POST['attachment_id']) ? absint($_POST['attachment_id']) : 0; | |
| 1034 | + $attachment = $id ? get_post($id) : null; | |
| 1035 | + | |
| 1036 | + if (!$attachment || $attachment->post_type !== 'attachment' || (int) $attachment->post_parent !== $post_id) { | |
| 1037 | + wp_send_json_error(__('The file could not be changed.', 'wp-attachments'), 400); | |
| 1038 | + } | |
| 1039 | + | |
| 1040 | + if ('delete' === $action) { | |
| 1041 | + // wp_delete_attachment() also removes the files from disk. | |
| 1042 | + $ok = current_user_can('delete_post', $id) && wp_delete_attachment($id, true); | |
| 1043 | + } else { | |
| 1044 | + $ok = current_user_can('edit_post', $id) | |
| 1045 | + && !is_wp_error(wp_update_post(array('ID' => $id, 'post_parent' => 0), true)); | |
| 1046 | + } | |
| 1047 | + | |
| 1048 | + if (!$ok) { | |
| 1049 | + wp_send_json_error(__('The file could not be changed.', 'wp-attachments'), 403); | |
| 1050 | + } | |
| 1051 | + | |
| 1052 | + // Refreshed counters, and the empty state once nothing is left. | |
| 1053 | + $remaining = get_posts(array( | |
| 1054 | + 'post_parent' => $post_id, | |
| 1055 | + 'post_type' => 'attachment', | |
| 1056 | + 'post_status' => 'any', | |
| 1057 | + 'posts_per_page' => -1, | |
| 1058 | + 'fields' => 'ids', | |
| 1059 | + )); | |
| 1060 | + | |
| 1061 | + ob_start(); | |
| 1062 | + $this->renderStats($this->getStats($remaining)); | |
| 1063 | + $stats = ob_get_clean(); | |
| 1064 | + | |
| 1065 | + $empty = ''; | |
| 1066 | + if (empty($remaining)) { | |
| 1067 | + ob_start(); | |
| 1068 | + $this->printEmptyState(); | |
| 1069 | + $empty = ob_get_clean(); | |
| 1070 | + } | |
| 1071 | + | |
| 1072 | + wp_send_json_success(array( | |
| 1073 | + 'id' => $id, | |
| 1074 | + 'stats' => $stats, | |
| 1075 | + 'empty' => $empty, | |
| 1076 | + )); | |
| 1077 | + } | |
| 1078 | + | |
| 1079 | + /** | |
| 1116 | 1080 | * Render one row. Single source of truth for the item markup: printMetaBox() |
| 1117 | 1081 | * loops over it, and the attach AJAX handler buffers it for the response. |
| 1118 | 1082 | */ |
| 1119 | 1083 | private function print_single_attachment_item($attachment) |
| @@ -1120,17 +1084,17 @@ | ||
| 1120 | 1084 | { |
| 1121 | 1085 | $attachment_id = $attachment->ID; |
| 1122 | 1086 | $attachment_url = wp_get_attachment_url($attachment_id); |
| 1123 | 1087 | $attachment_mime = sanitize_title($attachment->post_mime_type); |
| 1124 | - $attachment_path = get_attached_file($attachment_id); | |
| 1125 | - $file_type = $this->getFileType($attachment->post_mime_type); | |
| 1088 | + $file_bytes = wpatt_get_attachment_filesize($attachment_id); | |
| 1089 | + $file_type = wpatt_get_file_type($attachment->post_mime_type); | |
| 1126 | 1090 | |
| 1127 | 1091 | $title = ('' !== trim((string) $attachment->post_title)) |
| 1128 | 1092 | ? $attachment->post_title |
| 1129 | 1093 | : __('(no title)', 'wp-attachments'); |
| 1130 | 1094 | |
| 1131 | - $file_size = ($attachment_path && file_exists($attachment_path)) | |
| 1132 | - ? wpatt_format_bytes(filesize($attachment_path), 1) | |
| 1095 | + $file_size = (false !== $file_bytes) | |
| 1096 | + ? wpatt_format_bytes($file_bytes, 1) | |
| 1133 | 1097 | : __('Not found', 'wp-attachments'); |
| 1134 | 1098 | |
| 1135 | 1099 | $formatted_date = $this->formatDate($attachment->post_date); |
| 1136 | 1100 | |
| @@ -1241,15 +1205,21 @@ | ||
| 1241 | 1205 | if (!isset($_POST['wpa_checkfieldpreventautosaveonnewcpt'])) { |
| 1242 | 1206 | // Don't update meta if our box wasn't submitted (e.g. auto-draft) |
| 1243 | 1207 | return; |
| 1244 | 1208 | } |
| 1245 | - if ( isset($_POST["wpa_off"]) ) { | |
| 1246 | - delete_post_meta($post_id, "wpa_off"); | |
| 1209 | + if (wp_is_post_revision($post_id)) { | |
| 1210 | + return; | |
| 1211 | + } | |
| 1212 | + // No toggle is printed while the frontend is off for this post type: | |
| 1213 | + // keep the post's own choice instead of reading that as "hide". | |
| 1214 | + if (!wpatt_is_frontend_enabled(get_post_type($post_id))) { | |
| 1215 | + return; | |
| 1216 | + } | |
| 1217 | + | |
| 1218 | + // The checkbox is named after the old meta but means "show". | |
| 1219 | + if (isset($_POST['wpa_off'])) { | |
| 1220 | + delete_post_meta($post_id, 'wpa_off'); | |
| 1247 | 1221 | } else { |
| 1248 | - update_post_meta($post_id, "wpa_off", isset($_POST["wpa_off"]) ? '' : '1'); | |
| 1222 | + update_post_meta($post_id, 'wpa_off', '1'); | |
| 1249 | 1223 | } |
| 1250 | -}); | |
| 1251 | - | |
| 1252 | -add_action('plugins_loaded', function() { | |
| 1253 | - load_plugin_textdomain('wp-attachments', false, dirname(plugin_basename(__FILE__)) . '/languages/'); | |
| 1254 | 1224 | }); |
| 1255 | 1225 | ?> |