{"id":366308,"date":"2026-09-15T10:26:18","date_gmt":"2026-09-15T10:26:18","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/vanquish-attach-me-for-woocommerce\/"},"modified":"2026-10-13T14:39:32","modified_gmt":"2026-10-13T14:39:32","slug":"vanquish-attach-me-for-woocommerce","status":"publish","type":"plugin","link":"https:\/\/kn.wordpress.org\/plugins\/vanquish-attach-me-for-woocommerce\/","author":14329766,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.5.0","stable_tag":"1.5.0","tested":"7.1.3","requires":"5.8","requires_php":"7.4","requires_plugins":null,"header_name":"Vanquish Attach Me for WooCommerce","header_author":"Vanquish","header_description":"Attach any file to any WooCommerce order or product, show it to the customer and send it with the order emails. Premium adds bulk product rules, customer approval, expiring files and more.","assets_banners_color":"e4dcee","last_updated":"2026-10-13 14:39:32","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/wordpress.org\/plugins\/vanquish-attach-me-for-woocommerce\/","header_author_uri":"https:\/\/vanquishplugins.com\/","rating":5,"author_block_rating":0,"active_installs":10,"downloads":528,"num_ratings":2,"support_threads":1,"support_threads_resolved":1,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.0.0":{"tag":"1.0.0","author":"vanquish83","date":"2026-09-15 10:25:56","revision":3696741},"1.0.1":{"tag":"1.0.1","author":"vanquish83","date":"2026-09-16 15:04:16","revision":3698850},"1.1.0":{"tag":"1.1.0","author":"vanquish83","date":"2026-09-30 14:05:12","revision":3721411},"1.2.0":{"tag":"1.2.0","author":"vanquish83","date":"2026-10-02 09:07:32","revision":3724422},"1.3.0":{"tag":"1.3.0","author":"vanquish83","date":"2026-10-02 17:51:38","revision":3725214},"1.4.0":{"tag":"1.4.0","author":"vanquish83","date":"2026-10-07 15:39:55","revision":3732905},"1.5.0":{"tag":"1.5.0","author":"vanquish83","date":"2026-10-13 14:39:32","revision":3744209}},"upgrade_notice":{"1.5.0":"<p>The screens where files are attached have been redrawn, and files show the name they were uploaded with. New: a largest file to attach to emails. Premium: clean up old orders&#039; files, preview a message, proofs from the media library. Theme copies of the proof templates need updating.<\/p>","1.4.0":"<p>Premium: proofs \u2014 files sent for the customer&#039;s approval, with a conversation, versions, reminders and automatic approval. Approvals already set on order attachments become proofs automatically, with their answers and dates.<\/p>","1.3.0":"<p>Product files can each choose their place on the product page, be grouped in sections and shown as a compact list, and appear anywhere through a new block. Nothing moves on update. Premium: bulk order attachments, and the bulk rules and CSV import now share one menu entry.<\/p>","1.2.0":"<p>Shows each file&#039;s type and size, lets product files sit beside the price, and keeps a download history. Downloads by the shop&#039;s own staff are no longer counted, so they no longer use up a customer&#039;s download limit.<\/p>","1.1.0":"<p>Adds Default options for new attachments and a tidier attachment form, with the less common settings in a collapsible section. Nothing changes on attachments you have already saved.<\/p>","1.0.1":"<p>Fixes the legacy data importer on stores that do not use HPOS: it could report data that is not there and run without finishing. Recommended for everyone.<\/p>","1.0.0":"<p>First release. If you are coming from the CodeCanyon &quot;WooCommerce Attach Me!&quot; plugin, install this one alongside it and run the importer from Attach Me \u2192 Settings \u2192 Import old data; nothing is deleted from the old plugin.<\/p>"},"ratings":{"1":0,"2":0,"3":0,"4":0,"5":2},"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3696741,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3696741,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3698863,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3698863,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{"blueprint.json":{"filename":"blueprint.json","revision":3744254,"resolution":false,"location":"assets","locale":"","contents":"{\"$schema\":\"https:\\\/\\\/playground.wordpress.net\\\/blueprint-schema.json\",\"landingPage\":\"\\\/wp-admin\\\/admin.php?page=wc-orders\",\"preferredVersions\":{\"php\":\"8.2\",\"wp\":\"latest\"},\"phpExtensionBundles\":[\"kitchen-sink\"],\"features\":{\"networking\":true},\"steps\":[{\"step\":\"login\",\"username\":\"admin\",\"password\":\"password\"},{\"step\":\"installPlugin\",\"pluginData\":{\"resource\":\"wordpress.org\\\/plugins\",\"slug\":\"woocommerce\"},\"options\":{\"activate\":true}},{\"step\":\"installPlugin\",\"pluginData\":{\"resource\":\"wordpress.org\\\/plugins\",\"slug\":\"vanquish-attach-me-for-woocommerce\"},\"options\":{\"activate\":true}},{\"step\":\"installTheme\",\"themeData\":{\"resource\":\"wordpress.org\\\/themes\",\"slug\":\"emoza-woocommerce\"},\"options\":{\"activate\":true}},{\"step\":\"runPHP\",\"code\":\"<?php\\n\\\/**\\n * Live Preview seeding for WordPress Playground.\\n *\\n * This is the SOURCE of the runPHP step in blueprint.json (see build.py). It runs\\n * AFTER WooCommerce and the FREE build of the plugin are active.\\n *\\n * What it has to solve: a fresh store has no orders, and a plugin that attaches\\n * files to orders has nothing to show on a store with no orders. So the seed\\n * builds a small print shop -- the kind of business that sends proofs, invoices\\n * and certificates -- with three orders in different states, real files attached\\n * to two of them, and product files on every product.\\n *\\n * The landing page is the admin orders list, where the Attachments column shows\\n * which orders carry files and its Manage button opens them without leaving the\\n * list. The customer's side is one click away: the orders belong to the signed-in\\n * account, so My account -> Orders shows the same files as the buyer sees them.\\n *\\n * Every attachment goes through the plugin's own services -- Storage::adopt_for()\\n * for the file, OrderAttachments and ProductAttachments for the record -- rather\\n * than being written into meta by hand. The demo data then passes the same\\n * sanitising and lands in the same protected folders as a real upload, and if\\n * the storage format ever changes the seed follows it instead of quietly\\n * producing records the plugin no longer reads.\\n *\\n * Landing on \\\/wp-admin\\\/admin.php?page=wc-orders assumes HPOS. WooCommerce makes\\n * it the default on new installs and Playground always installs the latest, so\\n * that route exists. The option is deliberately not toggled here: the data stores\\n * are chosen when WooCommerce boots, before this script runs, and switching mid-\\n * request would create the orders in one store and list them from the other.\\n *\\n * Closures, not named functions: PHP binds a top-level function declaration when\\n * the file is compiled, so a guard that returns early does not stop it being\\n * declared -- and this file must be safe to run twice.\\n *\\n * Idempotent: guarded by the vanam_demo_seeded option.\\n *\\\/\\n\\nrequire_once '\\\/wordpress\\\/wp-load.php';\\n\\nif ( get_option( 'vanam_demo_seeded' ) ) {\\n\\treturn;\\n}\\n\\nuse Vanquish\\\\AttachMe\\\\Com\\\\Attachment;\\nuse Vanquish\\\\AttachMe\\\\Com\\\\OrderAttachments;\\nuse Vanquish\\\\AttachMe\\\\Com\\\\ProductAttachments;\\nuse Vanquish\\\\AttachMe\\\\Com\\\\Settings;\\nuse Vanquish\\\\AttachMe\\\\Com\\\\Storage;\\n\\n\\\/* ---------------------------------------------------------------------------\\n * 1. Store scaffolding\\n * ------------------------------------------------------------------------ *\\\/\\n\\nupdate_option( 'blogname', 'Vanquish Attach Me for WooCommerce' );\\n\\nif ( class_exists( 'WC_Install' ) ) {\\n\\tWC_Install::create_pages();\\n}\\n\\n\\\/* Recent WooCommerce hides a new store behind a \\\"coming soon\\\" page, which would\\n * put a splash screen between the visitor and the shop. *\\\/\\nupdate_option( 'woocommerce_coming_soon', 'no' );\\n\\nupdate_option( 'woocommerce_store_address', 'Via Roma 1' );\\nupdate_option( 'woocommerce_store_city', 'Pisa' );\\nupdate_option( 'woocommerce_default_country', 'IT:PI' );\\nupdate_option( 'woocommerce_store_postcode', '56100' );\\nupdate_option( 'woocommerce_currency', 'EUR' );\\n\\n\\\/* Tidy the front-end navigation: drop the default Sample Page and build a real\\n * menu, which also removes the theme's automatic \\\"Home\\\" fallback entry. *\\\/\\n$vanam_sample = get_page_by_path( 'sample-page' );\\nif ( $vanam_sample ) {\\n\\twp_delete_post( $vanam_sample->ID, true );\\n}\\n\\nif ( function_exists( 'wc_get_page_id' ) && ! wp_get_nav_menu_object( 'vanam-demo-menu' ) ) {\\n\\t$vanam_menu_id = wp_create_nav_menu( 'vanam-demo-menu' );\\n\\n\\tforeach ( array(\\n\\t\\t'Shop'       => wc_get_page_id( 'shop' ),\\n\\t\\t'Cart'       => wc_get_page_id( 'cart' ),\\n\\t\\t'Checkout'   => wc_get_page_id( 'checkout' ),\\n\\t\\t'My account' => wc_get_page_id( 'myaccount' ),\\n\\t) as $vanam_label => $vanam_page_id ) {\\n\\t\\tif ( $vanam_page_id && $vanam_page_id > 0 ) {\\n\\t\\t\\twp_update_nav_menu_item(\\n\\t\\t\\t\\t$vanam_menu_id,\\n\\t\\t\\t\\t0,\\n\\t\\t\\t\\tarray(\\n\\t\\t\\t\\t\\t'menu-item-title'     => $vanam_label,\\n\\t\\t\\t\\t\\t'menu-item-object'    => 'page',\\n\\t\\t\\t\\t\\t'menu-item-object-id' => $vanam_page_id,\\n\\t\\t\\t\\t\\t'menu-item-type'      => 'post_type',\\n\\t\\t\\t\\t\\t'menu-item-status'    => 'publish',\\n\\t\\t\\t\\t)\\n\\t\\t\\t);\\n\\t\\t}\\n\\t}\\n\\n\\t$vanam_locations = get_theme_mod( 'nav_menu_locations' );\\n\\tif ( ! is_array( $vanam_locations ) ) {\\n\\t\\t$vanam_locations = array();\\n\\t}\\n\\tforeach ( array_keys( (array) get_registered_nav_menus() ) as $vanam_location ) {\\n\\t\\t$vanam_locations[ $vanam_location ] = $vanam_menu_id;\\n\\t}\\n\\tset_theme_mod( 'nav_menu_locations', $vanam_locations );\\n}\\n\\n\\\/* Payments and shipping, so the demo checkout can actually be completed:\\n * cash on delivery needs no keys, free shipping needs no configuration. *\\\/\\n$vanam_cod = get_option( 'woocommerce_cod_settings', array() );\\nif ( ! is_array( $vanam_cod ) ) {\\n\\t$vanam_cod = array();\\n}\\nif ( empty( $vanam_cod['enabled'] ) || 'yes' !== $vanam_cod['enabled'] ) {\\n\\t$vanam_cod['enabled']            = 'yes';\\n\\t$vanam_cod['title']              = 'Cash on delivery';\\n\\t$vanam_cod['enable_for_virtual'] = 'yes';\\n\\tupdate_option( 'woocommerce_cod_settings', $vanam_cod );\\n}\\n\\nif ( class_exists( 'WC_Shipping_Zone' ) ) {\\n\\t$vanam_zone     = new WC_Shipping_Zone( 0 ); \\\/\\\/ Anything not matched by another zone.\\n\\t$vanam_has_free = false;\\n\\tforeach ( $vanam_zone->get_shipping_methods() as $vanam_method ) {\\n\\t\\tif ( 'free_shipping' === $vanam_method->id ) {\\n\\t\\t\\t$vanam_has_free = true;\\n\\t\\t\\tbreak;\\n\\t\\t}\\n\\t}\\n\\tif ( ! $vanam_has_free ) {\\n\\t\\t$vanam_zone->add_shipping_method( 'free_shipping' );\\n\\t\\t$vanam_zone->save();\\n\\t}\\n}\\n\\n\\\/* ---------------------------------------------------------------------------\\n * 2. Plugin settings\\n *\\n * Image previews on: off is the right default for a real shop, where a file is\\n * often a PDF and a thumbnail adds nothing, but the demo carries a design proof,\\n * and seeing it is the fastest way to understand what the customer gets.\\n * ------------------------------------------------------------------------ *\\\/\\n\\nif ( class_exists( Settings::class ) ) {\\n\\tSettings::update( array( 'image_preview' => true ) );\\n}\\n\\n\\\/* The plugin is not there -- a failed install, a renamed class. Leave a working\\n * store rather than a fatal error in the middle of the preview. *\\\/\\nif ( ! class_exists( Storage::class ) || ! function_exists( 'wc_create_order' ) ) {\\n\\tupdate_option( 'vanam_demo_seeded', 1 );\\n\\treturn;\\n}\\n\\n\\\/* ---------------------------------------------------------------------------\\n * 3. The files\\n *\\n * Generated rather than shipped: a blueprint is one JSON file, and nothing in it\\n * can point at a binary. Real, valid files, so that downloading one from the\\n * preview opens a document rather than an error.\\n * ------------------------------------------------------------------------ *\\\/\\n\\n\\\/**\\n * A one-page PDF with a heading and a few lines, in the base Helvetica every\\n * reader has. The cross-reference offsets are measured, not hard-coded, so the\\n * file stays valid whatever the text is.\\n *\\\/\\n$vanam_pdf = function ( $title, array $lines ) {\\n\\t$escape = function ( $text ) {\\n\\t\\treturn str_replace( array( '\\\\\\\\', '(', ')' ), array( '\\\\\\\\\\\\\\\\', '\\\\\\\\(', '\\\\\\\\)' ), $text );\\n\\t};\\n\\n\\t$content = 'BT \\\/F1 22 Tf 64 740 Td (' . $escape( $title ) . \\\") Tj ET\\\\n\\\";\\n\\t$y       = 700;\\n\\n\\tforeach ( $lines as $line ) {\\n\\t\\t$content .= 'BT \\\/F1 12 Tf 64 ' . $y . ' Td (' . $escape( $line ) . \\\") Tj ET\\\\n\\\";\\n\\t\\t$y       -= 22;\\n\\t}\\n\\n\\t$objects = array(\\n\\t\\t'<< \\\/Type \\\/Catalog \\\/Pages 2 0 R >>',\\n\\t\\t'<< \\\/Type \\\/Pages \\\/Kids [3 0 R] \\\/Count 1 >>',\\n\\t\\t'<< \\\/Type \\\/Page \\\/Parent 2 0 R \\\/MediaBox [0 0 612 792] \\\/Resources << \\\/Font << \\\/F1 4 0 R >> >> \\\/Contents 5 0 R >>',\\n\\t\\t'<< \\\/Type \\\/Font \\\/Subtype \\\/Type1 \\\/BaseFont \\\/Helvetica >>',\\n\\t\\t'<< \\\/Length ' . strlen( $content ) . \\\" >>\\\\nstream\\\\n\\\" . $content . 'endstream',\\n\\t);\\n\\n\\t$pdf     = \\\"%PDF-1.4\\\\n\\\";\\n\\t$offsets = array();\\n\\n\\tforeach ( $objects as $index => $body ) {\\n\\t\\t$offsets[] = strlen( $pdf );\\n\\t\\t$pdf      .= ( $index + 1 ) . \\\" 0 obj\\\\n\\\" . $body . \\\"\\\\nendobj\\\\n\\\";\\n\\t}\\n\\n\\t$xref = strlen( $pdf );\\n\\t$pdf .= \\\"xref\\\\n0 \\\" . ( count( $objects ) + 1 ) . \\\"\\\\n0000000000 65535 f \\\\n\\\";\\n\\n\\tforeach ( $offsets as $offset ) {\\n\\t\\t$pdf .= sprintf( \\\"%010d 00000 n \\\\n\\\", $offset );\\n\\t}\\n\\n\\treturn $pdf . 'trailer << \\\/Size ' . ( count( $objects ) + 1 ) . \\\" \\\/Root 1 0 R >>\\\\nstartxref\\\\n\\\" . $xref . \\\"\\\\n%%EOF\\\\n\\\";\\n};\\n\\n\\\/**\\n * A mock business-card proof, drawn with GD. Empty when GD is missing, and the\\n * caller falls back to a PDF: a proof that cannot be previewed is better than no\\n * proof.\\n *\\\/\\n$vanam_png = function () {\\n\\tif ( ! function_exists( 'imagecreatetruecolor' ) ) {\\n\\t\\treturn '';\\n\\t}\\n\\n\\t$width  = 700;\\n\\t$height = 400;\\n\\t$image  = imagecreatetruecolor( $width, $height );\\n\\n\\t$paper  = imagecolorallocate( $image, 247, 243, 236 );\\n\\t$ink    = imagecolorallocate( $image, 40, 40, 40 );\\n\\t$muted  = imagecolorallocate( $image, 120, 120, 120 );\\n\\t$accent = imagecolorallocate( $image, 127, 84, 179 );\\n\\t$card   = imagecolorallocate( $image, 255, 255, 255 );\\n\\n\\timagefilledrectangle( $image, 0, 0, $width, $height, $paper );\\n\\n\\t\\\/\\\/ The card itself, with a bleed line around it, which is what a proof shows.\\n\\timagefilledrectangle( $image, 120, 90, 580, 330, $card );\\n\\timagerectangle( $image, 110, 80, 590, 340, $muted );\\n\\timagefilledrectangle( $image, 120, 90, 136, 330, $accent );\\n\\n\\timagestring( $image, 5, 170, 150, 'ANNA ROSSI', $ink );\\n\\timagestring( $image, 3, 170, 175, 'Graphic designer', $muted );\\n\\timagestring( $image, 3, 170, 250, 'anna@example.com', $ink );\\n\\timagestring( $image, 3, 170, 270, '+39 050 123456', $ink );\\n\\n\\timagestring( $image, 4, 24, 20, 'DESIGN PROOF - front - 85 x 55 mm', $accent );\\n\\timagestring( $image, 2, 24, 370, 'Grey line = bleed. Check spelling before approving.', $muted );\\n\\n\\tob_start();\\n\\timagepng( $image );\\n\\t$bytes = ob_get_clean();\\n\\timagedestroy( $image );\\n\\n\\treturn (string) $bytes;\\n};\\n\\n\\\/**\\n * Put generated bytes into an owner's protected folder, through the plugin.\\n *\\n * Written to the plugin's own temporary folder first and then adopted, which is\\n * exactly the route a chunked upload takes once its last piece has arrived.\\n *\\n * @return array|null The file fields of an attachment record.\\n *\\\/\\n$vanam_store = function ( $owner_type, $owner_id, $file_name, $bytes, $mime ) {\\n\\t$storage = new Storage();\\n\\t$dir     = $storage->temp_dir();\\n\\n\\tif ( '' === $dir || '' === $bytes ) {\\n\\t\\treturn null;\\n\\t}\\n\\n\\t$temp = $dir . 'demo-' . wp_generate_password( 12, false ) . '.part';\\n\\n\\tif ( false === file_put_contents( $temp, $bytes ) ) {\\n\\t\\treturn null;\\n\\t}\\n\\n\\t$stored = $storage->adopt_for( $owner_type, $owner_id, $temp, $file_name );\\n\\n\\tif ( is_wp_error( $stored ) ) {\\n\\t\\twp_delete_file( $temp );\\n\\t\\treturn null;\\n\\t}\\n\\n\\treturn array(\\n\\t\\t'source'    => Attachment::SOURCE_UPLOAD,\\n\\t\\t'file_path' => $stored,\\n\\t\\t'file_name' => $file_name,\\n\\t\\t'file_size' => strlen( $bytes ),\\n\\t\\t'mime'      => $mime,\\n\\t);\\n};\\n\\n\\\/* ---------------------------------------------------------------------------\\n * 4. Products, each with a file of its own\\n *\\n * One of each visibility, so the three places a product file can appear are all\\n * demonstrated: the product page before buying, the order after buying, both.\\n * ------------------------------------------------------------------------ *\\\/\\n\\n$vanam_catalog = array(\\n\\t'business-cards' => array(\\n\\t\\t'name'  => 'Custom Business Cards',\\n\\t\\t'price' => '39',\\n\\t\\t'file'  => array(\\n\\t\\t\\t'title'       => 'Artwork guidelines',\\n\\t\\t\\t'description' => 'Sizes, bleed and colour profile for the file you send us.',\\n\\t\\t\\t'name'        => 'artwork-guidelines.pdf',\\n\\t\\t\\t'visibility'  => ProductAttachments::VISIBLE_BOTH,\\n\\t\\t\\t'lines'       => array(\\n\\t\\t\\t\\t'Card size: 85 x 55 mm, plus 3 mm bleed on every side.',\\n\\t\\t\\t\\t'Colour: CMYK, FOGRA39. Black text as 100% K.',\\n\\t\\t\\t\\t'Resolution: 300 dpi. Fonts outlined or embedded.',\\n\\t\\t\\t\\t'Keep text at least 4 mm inside the trim line.',\\n\\t\\t\\t),\\n\\t\\t),\\n\\t),\\n\\t'wedding-invitations' => array(\\n\\t\\t'name'  => 'Wedding Invitation Set',\\n\\t\\t'price' => '120',\\n\\t\\t'file'  => array(\\n\\t\\t\\t'title'       => 'Paper and finish samples',\\n\\t\\t\\t'description' => 'The papers, weights and finishes the set can be printed on.',\\n\\t\\t\\t'name'        => 'paper-and-finishes.pdf',\\n\\t\\t\\t'visibility'  => ProductAttachments::VISIBLE_PRODUCT,\\n\\t\\t\\t'lines'       => array(\\n\\t\\t\\t\\t'Cotton 600 g - soft, textured, takes letterpress well.',\\n\\t\\t\\t\\t'Pearl 300 g - light shimmer, best with foil.',\\n\\t\\t\\t\\t'Recycled kraft 350 g - natural, rustic.',\\n\\t\\t\\t\\t'Finishes: gold foil, blind emboss, deckled edge.',\\n\\t\\t\\t),\\n\\t\\t),\\n\\t),\\n\\t'poster-a2' => array(\\n\\t\\t'name'  => 'Poster Print A2',\\n\\t\\t'price' => '25',\\n\\t\\t'file'  => array(\\n\\t\\t\\t'title'       => 'Framing and care guide',\\n\\t\\t\\t'description' => 'How to hang the poster and keep the colours from fading.',\\n\\t\\t\\t'name'        => 'framing-and-care.pdf',\\n\\t\\t\\t'visibility'  => ProductAttachments::VISIBLE_ORDER,\\n\\t\\t\\t'lines'       => array(\\n\\t\\t\\t\\t'Let the print rest flat for 24 hours before framing.',\\n\\t\\t\\t\\t'Use UV-filtering glass away from direct sunlight.',\\n\\t\\t\\t\\t'Handle by the edges; dust with a dry, soft cloth.',\\n\\t\\t\\t),\\n\\t\\t),\\n\\t),\\n);\\n\\n$vanam_product_ids = array();\\n\\nforeach ( $vanam_catalog as $vanam_slug => $vanam_entry ) {\\n\\t$vanam_existing = get_page_by_path( $vanam_slug, OBJECT, 'product' );\\n\\n\\tif ( $vanam_existing ) {\\n\\t\\t$vanam_product_ids[ $vanam_slug ] = $vanam_existing->ID;\\n\\t\\tcontinue;\\n\\t}\\n\\n\\tif ( ! class_exists( 'WC_Product_Simple' ) ) {\\n\\t\\tcontinue;\\n\\t}\\n\\n\\t$vanam_product = new WC_Product_Simple();\\n\\t$vanam_product->set_name( $vanam_entry['name'] );\\n\\t$vanam_product->set_slug( $vanam_slug );\\n\\t$vanam_product->set_status( 'publish' );\\n\\t$vanam_product->set_catalog_visibility( 'visible' );\\n\\t$vanam_product->set_regular_price( $vanam_entry['price'] );\\n\\t$vanam_product->save();\\n\\n\\t$vanam_product_id                 = $vanam_product->get_id();\\n\\t$vanam_product_ids[ $vanam_slug ] = $vanam_product_id;\\n\\n\\t$vanam_file = $vanam_store(\\n\\t\\tStorage::OWNER_PRODUCT,\\n\\t\\t$vanam_product_id,\\n\\t\\t$vanam_entry['file']['name'],\\n\\t\\t$vanam_pdf( $vanam_entry['file']['title'], $vanam_entry['file']['lines'] ),\\n\\t\\t'application\\\/pdf'\\n\\t);\\n\\n\\tif ( $vanam_file ) {\\n\\t\\t( new ProductAttachments() )->save_all(\\n\\t\\t\\t$vanam_product_id,\\n\\t\\t\\tarray(\\n\\t\\t\\t\\tarray_merge(\\n\\t\\t\\t\\t\\t$vanam_file,\\n\\t\\t\\t\\t\\tarray(\\n\\t\\t\\t\\t\\t\\t'title'       => $vanam_entry['file']['title'],\\n\\t\\t\\t\\t\\t\\t'description' => $vanam_entry['file']['description'],\\n\\t\\t\\t\\t\\t\\t'visibility'  => $vanam_entry['file']['visibility'],\\n\\t\\t\\t\\t\\t\\t'created'     => current_time( 'mysql' ),\\n\\t\\t\\t\\t\\t)\\n\\t\\t\\t\\t),\\n\\t\\t\\t)\\n\\t\\t);\\n\\t}\\n}\\n\\n\\\/* ---------------------------------------------------------------------------\\n * 5. Orders, with files\\n *\\n * All three belong to the signed-in account, so the visitor can open My account\\n * and see them as the customer does. The last one has no files of its own, on\\n * purpose: the Attachments column is easier to read with a zero next to the\\n * other counts.\\n * ------------------------------------------------------------------------ *\\\/\\n\\nwp_update_user(\\n\\tarray(\\n\\t\\t'ID'         => 1,\\n\\t\\t'first_name' => 'Anna',\\n\\t\\t'last_name'  => 'Rossi',\\n\\t)\\n);\\n\\n$vanam_orders = array(\\n\\tarray(\\n\\t\\t'product' => 'business-cards',\\n\\t\\t'status'  => 'processing',\\n\\t\\t'days'    => 1,\\n\\t\\t'files'   => array(\\n\\t\\t\\tarray(\\n\\t\\t\\t\\t'kind'        => 'proof',\\n\\t\\t\\t\\t'title'       => 'Design proof - front',\\n\\t\\t\\t\\t'description' => 'Please check <strong>spelling and phone number<\\\/strong> before we print. Reply to the order email with any change.',\\n\\t\\t\\t\\t'emails'      => array( 'customer_processing_order', 'customer_invoice' ),\\n\\t\\t\\t),\\n\\t\\t\\tarray(\\n\\t\\t\\t\\t'kind'        => 'pdf',\\n\\t\\t\\t\\t'title'       => 'Invoice',\\n\\t\\t\\t\\t'name'        => 'invoice-1001.pdf',\\n\\t\\t\\t\\t'description' => '',\\n\\t\\t\\t\\t'emails'      => array( 'customer_invoice', 'customer_completed_order' ),\\n\\t\\t\\t\\t'lines'       => array(\\n\\t\\t\\t\\t\\t'Invoice 1001 - Custom Business Cards x 1',\\n\\t\\t\\t\\t\\t'Subtotal: EUR 39.00',\\n\\t\\t\\t\\t\\t'VAT (22%): EUR 8.58',\\n\\t\\t\\t\\t\\t'Total: EUR 47.58',\\n\\t\\t\\t\\t),\\n\\t\\t\\t),\\n\\t\\t),\\n\\t\\t'email_block' => 'Hi [customer_name], your files for order [order_number] are ready. You can also find them any time on [order_page_link].',\\n\\t),\\n\\tarray(\\n\\t\\t'product' => 'poster-a2',\\n\\t\\t'status'  => 'completed',\\n\\t\\t'days'    => 6,\\n\\t\\t'files'   => array(\\n\\t\\t\\tarray(\\n\\t\\t\\t\\t'kind'        => 'pdf',\\n\\t\\t\\t\\t'title'       => 'Certificate of authenticity',\\n\\t\\t\\t\\t'name'        => 'certificate-of-authenticity.pdf',\\n\\t\\t\\t\\t'description' => 'Signed and numbered. Keep it with the print.',\\n\\t\\t\\t\\t'emails'      => array( 'customer_completed_order' ),\\n\\t\\t\\t\\t'lines'       => array(\\n\\t\\t\\t\\t\\t'This print is number 12 of a limited run of 50.',\\n\\t\\t\\t\\t\\t'Printed on archival cotton paper with pigment inks.',\\n\\t\\t\\t\\t\\t'Signed by the artist.',\\n\\t\\t\\t\\t),\\n\\t\\t\\t),\\n\\t\\t),\\n\\t\\t'email_block' => '',\\n\\t),\\n\\tarray(\\n\\t\\t'product'     => 'wedding-invitations',\\n\\t\\t'status'      => 'on-hold',\\n\\t\\t'days'        => 0,\\n\\t\\t'files'       => array(),\\n\\t\\t'email_block' => '',\\n\\t),\\n);\\n\\n$vanam_attachments = new OrderAttachments();\\n\\nforeach ( $vanam_orders as $vanam_data ) {\\n\\tif ( empty( $vanam_product_ids[ $vanam_data['product'] ] ) ) {\\n\\t\\tcontinue;\\n\\t}\\n\\n\\t$vanam_order = wc_create_order( array( 'customer_id' => 1 ) );\\n\\n\\tif ( is_wp_error( $vanam_order ) ) {\\n\\t\\tcontinue;\\n\\t}\\n\\n\\t$vanam_product = wc_get_product( $vanam_product_ids[ $vanam_data['product'] ] );\\n\\tif ( $vanam_product ) {\\n\\t\\t$vanam_order->add_product( $vanam_product, 1 );\\n\\t}\\n\\n\\t$vanam_address = array(\\n\\t\\t'first_name' => 'Anna',\\n\\t\\t'last_name'  => 'Rossi',\\n\\t\\t'email'      => 'anna@example.com',\\n\\t\\t'address_1'  => 'Via Roma 1',\\n\\t\\t'city'       => 'Pisa',\\n\\t\\t'postcode'   => '56100',\\n\\t\\t'country'    => 'IT',\\n\\t);\\n\\t$vanam_order->set_address( $vanam_address, 'billing' );\\n\\tunset( $vanam_address['email'] );\\n\\t$vanam_order->set_address( $vanam_address, 'shipping' );\\n\\n\\t$vanam_order->set_payment_method( 'cod' );\\n\\t$vanam_order->set_payment_method_title( 'Cash on delivery' );\\n\\t$vanam_order->set_date_created( time() - (int) $vanam_data['days'] * DAY_IN_SECONDS );\\n\\t$vanam_order->calculate_totals();\\n\\t$vanam_order->set_status( $vanam_data['status'] );\\n\\t$vanam_order->save();\\n\\n\\t$vanam_order_id = $vanam_order->get_id();\\n\\n\\tforeach ( $vanam_data['files'] as $vanam_spec ) {\\n\\t\\t$vanam_file = null;\\n\\n\\t\\tif ( 'proof' === $vanam_spec['kind'] ) {\\n\\t\\t\\t$vanam_file = $vanam_store( Storage::OWNER_ORDER, $vanam_order_id, 'business-card-proof.png', $vanam_png(), 'image\\\/png' );\\n\\t\\t}\\n\\n\\t\\t\\\/\\\/ A PDF when asked for one, and also when the proof could not be drawn.\\n\\t\\tif ( ! $vanam_file ) {\\n\\t\\t\\t$vanam_name  = isset( $vanam_spec['name'] ) ? $vanam_spec['name'] : 'business-card-proof.pdf';\\n\\t\\t\\t$vanam_lines = isset( $vanam_spec['lines'] ) ? $vanam_spec['lines'] : array( 'Anna Rossi - Graphic designer', 'anna@example.com - +39 050 123456' );\\n\\t\\t\\t$vanam_file  = $vanam_store( Storage::OWNER_ORDER, $vanam_order_id, $vanam_name, $vanam_pdf( $vanam_spec['title'], $vanam_lines ), 'application\\\/pdf' );\\n\\t\\t}\\n\\n\\t\\tif ( ! $vanam_file ) {\\n\\t\\t\\tcontinue;\\n\\t\\t}\\n\\n\\t\\t$vanam_attachments->add(\\n\\t\\t\\t$vanam_order,\\n\\t\\t\\tarray_merge(\\n\\t\\t\\t\\t$vanam_file,\\n\\t\\t\\t\\tarray(\\n\\t\\t\\t\\t\\t'title'       => $vanam_spec['title'],\\n\\t\\t\\t\\t\\t'description' => $vanam_spec['description'],\\n\\t\\t\\t\\t\\t'emails'      => $vanam_spec['emails'],\\n\\t\\t\\t\\t)\\n\\t\\t\\t)\\n\\t\\t);\\n\\t}\\n\\n\\tif ( '' !== $vanam_data['email_block'] ) {\\n\\t\\t$vanam_attachments->save_options(\\n\\t\\t\\t$vanam_order,\\n\\t\\t\\tarray(\\n\\t\\t\\t\\t'embed_enabled' => true,\\n\\t\\t\\t\\t'embed_text'    => $vanam_data['email_block'],\\n\\t\\t\\t)\\n\\t\\t);\\n\\t}\\n}\\n\\n\\\/* ---------------------------------------------------------------------------\\n * 6. Make the customer's pages reachable\\n *\\n * The visitor will click through to My account -> Orders -> View order, and\\n * those endpoints are rewrite rules. They are normally flushed on a later\\n * request; this preview has no later request to wait for.\\n * ------------------------------------------------------------------------ *\\\/\\n\\nflush_rewrite_rules();\\n\\n\\\/* ---------------------------------------------------------------------------\\n * 7. Freemius\\n *\\n * Skip the connection, so no opt-in screen or notice greets a visitor who only\\n * wanted to see the plugin. Guarded: Freemius state must never be able to break\\n * the preview.\\n * ------------------------------------------------------------------------ *\\\/\\n\\nif ( function_exists( 'vanam_fs' ) ) {\\n\\ttry {\\n\\t\\tif ( ! vanam_fs()->is_registered() ) {\\n\\t\\t\\tvanam_fs()->skip_connection();\\n\\t\\t}\\n\\t} catch ( \\\\Exception $e ) {\\n\\t\\t\\\/\\\/ Nothing to do: the preview works without it.\\n\\t}\\n}\\n\\n\\\/* Cancel Freemius' post-activation redirect.\\n *\\n * Freemius marks a fresh activation with a transient and, on the next admin page\\n * load, redirects to the plugin's own first page -- which would hijack the\\n * landing page and drop the visitor on Settings instead of the orders. The\\n * transient is what is_plugin_activation() reads, so removing it is enough;\\n * skip_connection() above does not clear it.\\n *\\\/\\ndelete_transient( 'fs_plugin_vanquish-attach-me-for-woocommerce_activated' );\\n\\nupdate_option( 'vanam_demo_seeded', 1 );\\n\"}]}"}},"all_blocks":{"vanquish-attach-me\/product-attachments":{"$schema":"https:\/\/schemas.wp.org\/trunk\/block.json","apiVersion":2,"name":"vanquish-attach-me\/product-attachments","title":"Product attachments","category":"widgets","icon":"paperclip","description":"A product's files: the current product's on a product page, or any product you pick.","keywords":["attachments","files","downloads","documents","manual"],"textdomain":"vanquish-attach-me-for-woocommerce","usesContext":["postId","postType"],"attributes":{"productId":{"type":"number","default":0},"place":{"type":"string","default":"all","enum":["all","tab","summary","after_cart"]},"showTitle":{"type":"boolean","default":true}},"supports":{"html":false,"align":["wide","full"],"spacing":{"margin":true,"padding":true}},"editorScript":"file:.\/index.js","style":"vanam-frontend"}},"tagged_versions":["1.0.0","1.0.1","1.1.0","1.2.0","1.3.0","1.4.0","1.5.0"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3744210,"resolution":"1","location":"assets","locale":"","width":1760,"height":2626},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3744210,"resolution":"2","location":"assets","locale":"","width":1760,"height":2310},"screenshot-3.png":{"filename":"screenshot-3.png","revision":3696741,"resolution":"3","location":"assets","locale":"","width":1515,"height":1004},"screenshot-4.png":{"filename":"screenshot-4.png","revision":3696741,"resolution":"4","location":"assets","locale":"","width":1345,"height":901},"screenshot-5.png":{"filename":"screenshot-5.png","revision":3696741,"resolution":"5","location":"assets","locale":"","width":1579,"height":1191},"screenshot-6.png":{"filename":"screenshot-6.png","revision":3744210,"resolution":"6","location":"assets","locale":"","width":1438,"height":2654},"screenshot-7.png":{"filename":"screenshot-7.png","revision":3744210,"resolution":"7","location":"assets","locale":"","width":1760,"height":1912},"screenshot-8.png":{"filename":"screenshot-8.png","revision":3744210,"resolution":"8","location":"assets","locale":"","width":2356,"height":3024},"screenshot-9.png":{"filename":"screenshot-9.png","revision":3744210,"resolution":"9","location":"assets","locale":"","width":2356,"height":1710}},"screenshots":{"1":"Files on a product: each one a row that says what is set on it. Open one to choose where the customer sees it, which variations it applies to and which order emails carry it. Availability, roles, download limits and the disclaimer are Premium.","2":"Files on an order, in the \"Files &amp; proofs\" box: the emails each file goes with, and the switch for the block of download links in the order emails.","3":"The attachments tab on the product page, as a customer sees it before buying.","4":"My account: a \"View attachments\" button on each order that has files.","5":"The customer's order page: the files attached to the order, and the ones that came with the product they bought.","6":"Premium: a proof on the customer's order page \u2014 the file to approve, its versions, the conversation, and the answer.","7":"Premium: proofs on the order screen \u2014 every version and message, and the reply box.","8":"Premium: bulk attachments \u2014 one file for many products, with the products each rule reaches.","9":"Premium: clean up \u2014 choose which old orders lose their files. The next step says how many they are before anything is deleted."}},"plugin_section":[],"plugin_tags":[232103,284860,280841,281068,283480],"plugin_category":[45,50],"plugin_contributors":[78154,269507],"plugin_business_model":[],"class_list":["post-366308","plugin","type-plugin","status-publish","hentry","plugin_tags-email-attachments","plugin_tags-file-approval","plugin_tags-order-attachments","plugin_tags-product-attachments","plugin_tags-proof-approval","plugin_category-ecommerce","plugin_category-media","plugin_contributors-freemius","plugin_contributors-vanquish83","plugin_committers-vanquish83","plugin_support_reps-supportvanquishplugins"],"banners":{"banner":"https:\/\/ps.w.org\/vanquish-attach-me-for-woocommerce\/assets\/banner-772x250.png?rev=3698863","banner_2x":"https:\/\/ps.w.org\/vanquish-attach-me-for-woocommerce\/assets\/banner-1544x500.png?rev=3698863","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/vanquish-attach-me-for-woocommerce\/assets\/icon-128x128.png?rev=3696741","icon_2x":"https:\/\/ps.w.org\/vanquish-attach-me-for-woocommerce\/assets\/icon-256x256.png?rev=3696741","generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/vanquish-attach-me-for-woocommerce\/assets\/screenshot-1.png?rev=3744210","caption":"Files on a product: each one a row that says what is set on it. Open one to choose where the customer sees it, which variations it applies to and which order emails carry it. Availability, roles, download limits and the disclaimer are Premium."},{"src":"https:\/\/ps.w.org\/vanquish-attach-me-for-woocommerce\/assets\/screenshot-2.png?rev=3744210","caption":"Files on an order, in the \"Files &amp; proofs\" box: the emails each file goes with, and the switch for the block of download links in the order emails."},{"src":"https:\/\/ps.w.org\/vanquish-attach-me-for-woocommerce\/assets\/screenshot-3.png?rev=3696741","caption":"The attachments tab on the product page, as a customer sees it before buying."},{"src":"https:\/\/ps.w.org\/vanquish-attach-me-for-woocommerce\/assets\/screenshot-4.png?rev=3696741","caption":"My account: a \"View attachments\" button on each order that has files."},{"src":"https:\/\/ps.w.org\/vanquish-attach-me-for-woocommerce\/assets\/screenshot-5.png?rev=3696741","caption":"The customer's order page: the files attached to the order, and the ones that came with the product they bought."},{"src":"https:\/\/ps.w.org\/vanquish-attach-me-for-woocommerce\/assets\/screenshot-6.png?rev=3744210","caption":"Premium: a proof on the customer's order page \u2014 the file to approve, its versions, the conversation, and the answer."},{"src":"https:\/\/ps.w.org\/vanquish-attach-me-for-woocommerce\/assets\/screenshot-7.png?rev=3744210","caption":"Premium: proofs on the order screen \u2014 every version and message, and the reply box."},{"src":"https:\/\/ps.w.org\/vanquish-attach-me-for-woocommerce\/assets\/screenshot-8.png?rev=3744210","caption":"Premium: bulk attachments \u2014 one file for many products, with the products each rule reaches."},{"src":"https:\/\/ps.w.org\/vanquish-attach-me-for-woocommerce\/assets\/screenshot-9.png?rev=3744210","caption":"Premium: clean up \u2014 choose which old orders lose their files. The next step says how many they are before anything is deleted."}],"raw_content":"<!--section=description-->\n<p>Vanquish Attach Me for WooCommerce lets you give each customer the files that belong to their order, straight from the order screen: the proof they have to approve, their invoice, a certificate, the finished design. They find them on their order page and in the order emails, behind a link only they can open. Files that belong to a whole product \u2014 a manual, a size chart, a data sheet \u2014 work the same way, on the product page, after purchase, or both. Upload the file, pick one from the media library, or point at a URL.<\/p>\n\n<p>Uploaded files are not left where a URL can find them: they sit behind server rules and an unguessable path, and they are served through an endpoint that checks who is asking \u2014 the customer who placed that order, or somebody who can manage the shop. That is not a setting you can turn off \u2014 it is the only correct way to serve a file attached to an order, so it is simply how the plugin works.<\/p>\n\n<p>Large files go up in pieces, so your server's per-request upload limit is not the limit on what you can attach.<\/p>\n\n<p><strong>Proofs: file approval with your customer (Premium).<\/strong> Send a design, a print layout or a translation from the order for the customer to approve. They approve or reject it on their order page and you write to each other; every new version asks for approval again, and the whole history stays on the order. Reminders, automatic approval after a number of days, and a one-click import from the CodeCanyon plugin WooCommerce File Approval.<\/p>\n\n<h4>Free features<\/h4>\n\n<ul>\n<li>Attach any number of files to an order: upload them, choose them from the media library, or link to an external URL.<\/li>\n<li>A title and a description for each file, shown to the customer.<\/li>\n<li>Attach files to products, with a choice of which variations they apply to.<\/li>\n<li>Show a product's files on the product page, on the order page after buying, or both.<\/li>\n<li>Files attached to the standard WooCommerce emails (processing, completed, invoice, refunded) and to custom emails registered by other plugins, chosen per file.<\/li>\n<li>A block inside the order emails with your own wording and the download links, with placeholders for <code>[order_number]<\/code>, <code>[customer_name]<\/code> and <code>[order_page_link]<\/code> that a click writes into the text.<\/li>\n<li>Hide a file while the order is in a given status.<\/li>\n<li>Default options: the emails, the hidden statuses and the email block a new attachment starts with, set once instead of on every file, for order attachments, product attachments or both.<\/li>\n<li>A list you can read at a glance: each file is a row that shows its type, its size and what is set on it \u2014 the emails it goes with, where it shows, when it expires. Open a row to edit it, drop files on the list to add them.<\/li>\n<li>The largest file to attach to an email, set once: a bigger file goes out as a download link in the same email, so an oversized attachment never costs the customer the whole message.<\/li>\n<li>Files keep the name they were uploaded with, on the order, in the download and in the email. The copy on your server keeps its unguessable name.<\/li>\n<li>Each file's type and size under its name \u2014 \"PDF \u00b7 2.4 MB\" \u2014 so the customer knows what they are about to open.<\/li>\n<li>Image previews, at a thumbnail size you choose, and a configurable position for the attachments box on the order page.<\/li>\n<li>A \"View attachments\" button in the customer's order list.<\/li>\n<li>A product's files in a tab of their own, or beside the price: under the short description or after the \"Add to cart\" button \u2014 chosen for the whole shop, and per file where one belongs somewhere else.<\/li>\n<li>Sections on the product page \u2014 \"Manuals\", \"Certificates\" \u2014 optionally folded, and a choice of cards or a compact list.<\/li>\n<li>A <strong>Product attachments block<\/strong>, for a block theme's product template or any page: the current product's files, or any product's.<\/li>\n<li>An attachments column in the admin orders list, a \"Manage\" modal for handling them without opening the order, a filter for orders that have attachments, and a bulk action to delete them. The products list has the same bulk action.<\/li>\n<li>Every customer-facing text is editable \u2014 and, with WPML or Polylang active, editable per language.<\/li>\n<li>Template overrides from your theme, HPOS (High-Performance Order Storage) support.<\/li>\n<li>Migrates automatically from the legacy \"WooCommerce Attach Me!\" (CodeCanyon) plugin: settings, product attachments and every order's files.<\/li>\n<\/ul>\n\n<h4>Premium features<\/h4>\n\n<ul>\n<li><strong>Bulk product attachments<\/strong> \u2014 one rule attaches a file to many products or categories at once: all products, only the ones you pick, or all except those, with or without child categories. The rule counts the products it reaches as you build it, and can be duplicated. No opening a thousand products.<\/li>\n<li><strong>Bulk order attachments<\/strong> \u2014 one file for the orders you pick by number, or for every order: terms and conditions, a warranty, a notice. Kept once in its rule, shown next to each order's own files and sent with the emails you choose. Every product and order lists the bulk attachments that reach it.<\/li>\n<li><strong>Proofs \/ approval requests<\/strong> \u2014 send a file from the order for the customer to approve: a design, a print layout, a translation, uploaded or picked from the media library. They approve or reject it on their order page, you write to each other, and every new version you send asks for approval again, with the whole history kept. The customer can add files to their answers. Their verdict can move the order to another status; emails to each side are grouped, so three files sent in a row make one email. Reminders when nobody answers, and automatic approval after a number of days, announced to the customer beforehand. A \"Files to approve\" page in My account, and every proof of every order in one list.<\/li>\n<li><strong>Expiry<\/strong> \u2014 a file that stops being available on a fixed date, or a set time after the order. It disappears from the order page, the download link stops working, and the file can be deleted from the server automatically.<\/li>\n<li><strong>All attachments<\/strong> \u2014 every order's files on one screen: search by file, order or customer, see which nobody has downloaded yet and which expire this week, and delete in bulk \u2014 every expired file in one click. A second tab lists every file sent for approval: what is waiting, rejected and approved.<\/li>\n<li><strong>Clean up old orders<\/strong> \u2014 free disk space by deleting the attachments and proofs of orders placed before a date, or more than three months to two years ago, in the statuses you choose. The page says how many orders it is about before anything is deleted, asks you to confirm, works a few orders at a time and carries on from where it stopped if a request fails. The same cleanup can run by itself every night. Each order keeps a note of what was removed.<\/li>\n<li><strong>Download history<\/strong> \u2014 see on every order whether the customer has downloaded each file, and when: under the file's name, in full when you open it, and as an order note the first time. No IP address or other personal data is kept.<\/li>\n<li><strong>Download limits and a required disclaimer<\/strong> \u2014 a maximum number of downloads per file, and terms the customer must accept before the first one.<\/li>\n<li><strong>Visibility by user role<\/strong>, including visitors who are not signed in, on product attachments and bulk product attachments.<\/li>\n<li><strong>Automatic email files<\/strong> \u2014 a file that goes out with every copy of a chosen email, whatever the order contains: terms on every invoice, a returns form on every completed order. Any email WooCommerce sends to a customer, including the ones about an account rather than an order: new account, password reset.<\/li>\n<li><strong>A message written by hand<\/strong> \u2014 send the customer an email from the order screen, with whichever of that order's files you choose attached or linked, in your shop's own email template. Preview it before it goes; it leaves an order note saying what went out.<\/li>\n<li><strong>A library of preset texts<\/strong> \u2014 messages written once and offered under every editor by an \"Insert template\" button, so a shop that says the same thing on every order writes it once.<\/li>\n<li><strong>CSV import<\/strong> \u2014 one row, one link, one order or one product (by id or SKU), for a shop that already has its files listed somewhere else. Drag the file in; comma, semicolon or tab separated.<\/li>\n<li><strong>My Account \u2192 Downloads<\/strong> \u2014 the attachments listed on the page that claims to list everything the customer can download.<\/li>\n<li><strong>Shortcodes<\/strong> \u2014 put the attachments, or a single download link, on a page of your own. Each shows nothing at all unless the person reading the page is entitled to that order.<\/li>\n<li><strong>Files only in the emails<\/strong> \u2014 attached to the notification but never shown on the site.<\/li>\n<li><strong>Copy the download link<\/strong> with one click, on the customer's side.<\/li>\n<li><strong>Premium default options<\/strong> \u2014 what a new proof starts with, the download terms and the copy-link button, and the manual message to the customer, set once.<\/li>\n<li><strong>Moving from WooCommerce File Approval<\/strong> \u2014 its files, conversations, customers' files, answers, settings and preset answers become proofs, from one button.<\/li>\n<\/ul>\n\n<h3>External services<\/h3>\n\n<p><strong>The free version does not send any data to external services.<\/strong> Files you upload stay on your own server, and the download links point at your own site.<\/p>\n\n<p>This plugin uses <strong>Freemius<\/strong> to manage licensing and updates for the premium version, and to offer an optional opt-in when you first activate it. Nothing is sent unless you opt in or activate a licence; if you do, Freemius receives your site URL, WordPress and PHP versions and your administrator email address, in order to deliver updates and support. See <a href=\"https:\/\/freemius.com\/\">freemius.com<\/a>, its <a href=\"https:\/\/freemius.com\/terms\/\">terms<\/a> and its <a href=\"https:\/\/freemius.com\/privacy\/\">privacy policy<\/a>.<\/p>\n\n<p>The <strong>premium version<\/strong> adds no external services of its own: bulk product attachments, approval, expiry, automatic emails and the manual notification all run on your site, and the emails go out through WooCommerce.<\/p>\n\n<h4>More WooCommerce plugins by Vanquish<\/h4>\n\n<ul>\n<li><a href=\"https:\/\/wordpress.org\/plugins\/vanquish-upload-files-for-woocommerce\/\">Vanquish Upload Files for WooCommerce<\/a> - let customers upload files (even large ones) on the product, cart, checkout and order pages, for custom, personalized and print-on-demand products.<\/li>\n<li><a href=\"https:\/\/wordpress.org\/plugins\/vanquish-shipping-tracking-for-woocommerce\/\">Vanquish Shipping Tracking for WooCommerce<\/a> - tracking numbers on orders and emails, with 1,600+ carriers and their logos, a direct tracking link and a Track button. No account needed.<\/li>\n<li><a href=\"https:\/\/wordpress.org\/plugins\/vanquish-multiple-addresses-for-woocommerce\/\">Vanquish Multiple Addresses for WooCommerce<\/a> - give customers an address book: save multiple billing and shipping addresses and pick one at checkout.<\/li>\n<\/ul>\n\n<!--section=installation-->\n<ol>\n<li>Upload the plugin files to the <code>\/wp-content\/plugins\/vanquish-attach-me-for-woocommerce<\/code> directory, or install the plugin through the WordPress plugins screen.<\/li>\n<li>Activate the plugin through the 'Plugins' screen in WordPress.<\/li>\n<li>Make sure WooCommerce is installed and active.<\/li>\n<li>Configure the plugin from the \"Attach Me\" menu.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"where%20are%20the%20uploaded%20files%20kept%3F\"><h3>Where are the uploaded files kept?<\/h3><\/dt>\n<dd><p>In a folder inside your uploads directory, three ways round at once. The plugin writes the rules that close a directory to direct access, in the forms Apache and IIS understand. Because nginx honours neither, the path is unguessable as well: each order's files sit under a directory name derived from a secret the plugin generates for your site, rather than from the order number, and every stored file keeps its own name with twelve random characters added.<\/p>\n\n<p>And the way in is the only way in: every download goes through a signed link, which checks whether the person asking placed that order or can manage the shop.<\/p>\n\n<p>There is no switch for any of this. A file attached to an order is private by definition, and an option to serve it insecurely would only ever be turned on by mistake.<\/p><\/dd>\n<dt id=\"can%20i%20attach%20a%20file%20that%20is%20bigger%20than%20my%20server%27s%20upload%20limit%3F\"><h3>Can I attach a file that is bigger than my server's upload limit?<\/h3><\/dt>\n<dd><p>Yes. Files are sent to the server in pieces small enough to clear <code>upload_max_filesize<\/code> and <code>post_max_size<\/code>, so neither caps what you can attach. The screen shows the maximum it will accept.<\/p><\/dd>\n<dt id=\"what%20about%20files%20in%20the%20media%20library%2C%20or%20on%20another%20server%3F\"><h3>What about files in the media library, or on another server?<\/h3><\/dt>\n<dd><p>Both work. A media library file keeps its own public address in <code>wp-content\/uploads<\/code> \u2014 that is how the media library works \u2014 so if a file must not be reachable by anyone holding its URL, upload it through the plugin instead of adding it to the library. An external URL is only ever a link: the plugin does not fetch somebody else's file to attach it to your emails.<\/p><\/dd>\n<dt id=\"does%20it%20work%20with%20hpos%20%28high-performance%20order%20storage%29%3F\"><h3>Does it work with HPOS (High-Performance Order Storage)?<\/h3><\/dt>\n<dd><p>Yes, with HPOS and with the classic order storage.<\/p><\/dd>\n<dt id=\"i%20am%20migrating%20from%20the%20codecanyon%20%22woocommerce%20attach%20me%21%22%20plugin.%20do%20i%20lose%20anything%3F\"><h3>I am migrating from the CodeCanyon \"WooCommerce Attach Me!\" plugin. Do I lose anything?<\/h3><\/dt>\n<dd><p>No. Your settings, your texts, the files on your products and the files on every order are converted for you. The importer runs from <strong>Attach Me \u2192 Settings \u2192 Import old data<\/strong>, shows how much is left as it goes, and finishes in the background if you close the tab. An order is also converted the first time somebody opens it, whatever happened before.<\/p>\n\n<p>Your files stay where they are on disk and keep working, and the old plugin's download links are still understood. A customer with an account follows one after signing in, and so do you.<\/p>\n\n<p>A link to a <strong>guest<\/strong> order's file needs one thing more than the link. Those old URLs were built as <code>?wcam_id=&lt;order number&gt;-&lt;0, 1, 2...&gt;<\/code>, which anybody can type out, and a guest order has no account to check the visitor against \u2014 so on its own such a link is not proof of anything, and is refused. It works when the request also carries the order key, which is the token WooCommerce puts in the order links it emails: following the file from the customer's own order page works, pasting the bare old URL does not.<\/p>\n\n<p>The old plugin's data is left in place rather than deleted, so nothing is destroyed by importing. You can keep both installed while you check the result, then deactivate the old one.<\/p><\/dd>\n<dt id=\"i%20use%20the%20codecanyon%20%22woocommerce%20file%20approval%22%20plugin.%20can%20i%20move%3F\"><h3>I use the CodeCanyon \"WooCommerce File Approval\" plugin. Can I move?<\/h3><\/dt>\n<dd><p>Yes: proofs are its successor, in Premium. Under <strong>Attach Me \u2192 Settings \u2192 Proofs \/ File approval<\/strong>, a card appears on any site that has its data, and imports it in one go: each file becomes a proof on its order, with its conversation, the files the customer sent and the customer's answer, each with its date. Its settings and preset answers can come along too. Nothing of the old plugin is changed or deleted, and the import can be run again: what was already imported is skipped.<\/p>\n\n<p>File Approval replaced a file when a new one was sent and kept no history of it, so each proof starts with one version: the file as it is now. The files your customers sent are copied into the protected folder; File Approval kept them in a public one.<\/p><\/dd>\n<dt id=\"do%20the%20premium%20features%20change%20how%20the%20free%20ones%20behave%3F\"><h3>Do the premium features change how the free ones behave?<\/h3><\/dt>\n<dd><p>No. The premium package is the same plugin with more in it. Everything described above under \"free features\" works the same either way, and the settings you have already made are untouched by activating a licence.<\/p><\/dd>\n<dt id=\"how%20much%20does%20premium%20cost%2C%20and%20how%20do%20i%20get%20it%3F\"><h3>How much does Premium cost, and how do I get it?<\/h3><\/dt>\n<dd><p>There are monthly, yearly and lifetime plans, for one site up to ten. The current prices are on the <a href=\"https:\/\/vanquishplugins.com\/migration\/pricing\/\">pricing page<\/a>.<\/p>\n\n<p>To order, install and activate the free version, then go to <strong>Attach Me \u2192 Upgrade<\/strong> in your WordPress admin. The plans and a secure checkout, handled by Freemius, are right there, and the same screen walks you through activating Premium on your site.<\/p><\/dd>\n<dt id=\"can%20i%20try%20the%20plugin%20before%20buying%20premium%3F\"><h3>Can I try the plugin before buying Premium?<\/h3><\/dt>\n<dd><p>Yes, and it is the best way to start. The free version on WordPress.org is the same plugin with fewer features: install it on your own site, with your own theme, and check that the attachments look right on your order pages, your product pages and in your emails before upgrading. Premium adds features on top of it, on the same foundations.<\/p><\/dd>\n<dt id=\"my%20mail%20server%20refuses%20large%20attachments.%20what%20can%20i%20do%3F\"><h3>My mail server refuses large attachments. What can I do?<\/h3><\/dt>\n<dd><p>Set <strong>Attach Me \u2192 Settings \u2192 General \u2192 Emails \u2192 Largest file to attach<\/strong>. A file over that size is not attached: the email carries a download link to it instead, in the same place as the other links. Files under it are attached as before.<\/p><\/dd>\n<dt id=\"can%20i%20change%20the%20wording%20the%20customer%20sees%3F\"><h3>Can I change the wording the customer sees?<\/h3><\/dt>\n<dd><p>Yes, all of it, under <strong>Attach Me \u2192 Settings<\/strong>: the box title, the button, the empty message, the email block. With WPML or Polylang active, each text has one input per language.<\/p><\/dd>\n<dt id=\"what%20happens%20if%20i%20uninstall%20the%20plugin%3F\"><h3>What happens if I uninstall the plugin?<\/h3><\/dt>\n<dd><p>Nothing of yours is removed. Your settings and your wording stay, the files attached to your orders and products stay, and the files on disk are left alone \u2014 so reinstalling puts you back exactly where you were. Only two things go: the plugin's scheduled events, which would otherwise keep firing for a plugin that is no longer installed, and its caches, which would expire on their own anyway.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.5.0<\/h4>\n\n<ul>\n<li>New: the screens where files are attached have been redrawn. On the order, on the product and in Premium's bulk attachments, automatic email files and preset texts, each file is a row that says what it is and what is set on it; one row is open at a time, and files can be dropped on the list. Emails and order statuses are picked as pills, switches replace checkboxes, and \"Access &amp; limits\" says in its heading what it holds.<\/li>\n<li>New: the order's box is now \"Files &amp; proofs\", in tabs: Files, Proofs \/ File approval and Message the customer. The switch for the download links in the order emails saves itself.<\/li>\n<li>New: the largest file to attach to an email (Settings \u2192 General \u2192 Emails). A bigger file goes out as a download link in the same email. 0, the default, attaches files of any size.<\/li>\n<li>New: \"Delete attachments\" among the bulk actions of the products list. It asks first, and so does the one in the orders list.<\/li>\n<li>New: placeholders under an editor are buttons that write themselves into the text.<\/li>\n<li>New (Premium): Clean up, a tab of Bulk attachments. Delete the attachments and proofs of orders older than a date or a period, by status: it counts the orders first, asks you to confirm, works in small groups and can carry on from where it stopped. One automatic rule can repeat it every night. Each order keeps a note of what was removed.<\/li>\n<li>New (Premium): proofs redrawn on both sides. On the order: one row per file with its status and last activity, a list of versions, the conversation, and \"Attach a new version\" in the reply box. For the customer: a larger preview that opens over the page, the list of versions, and an answer in two steps.<\/li>\n<li>New (Premium): a file to approve can be picked from the media library, and so can a new version of it.<\/li>\n<li>New (Premium): the files a customer adds to an answer go up in pieces with a progress bar, so the server's upload limit is not theirs. A file sent by a customer can be deleted from the conversation.<\/li>\n<li>New (Premium): preview a message written by hand before sending it, in your shop's email template.<\/li>\n<li>New (Premium): duplicate a bulk rule or a preset text. A bulk rule says how many products or orders it reaches.<\/li>\n<li>New (Premium): \"Insert template\" under every editor, in place of the \"Load a preset text\" list. The text goes in where the cursor is; it no longer replaces what was written. Preset texts can be searched.<\/li>\n<li>New (Premium): automatic email files choose between order emails and account emails, and a file is told when it is heavy for an email.<\/li>\n<li>Changed: a file is shown, downloaded and attached to emails under the name it was uploaded with, including the files already on your orders. On the server it keeps its unguessable name. Email attachments need WordPress 6.2 or later for this.<\/li>\n<li>Changed (Premium): the list of proofs moved from its own menu entry to a tab of All attachments. The old address still works.<\/li>\n<li>Changed (Premium): a bulk product rule applies to \"All products\", \"Only these\" or \"All except these\". \"Only these\" with nothing picked now reaches no product; rules saved before that had nothing picked still reach all of them.<\/li>\n<li>Changed (Premium): an automatic email file saved before its emails are picked is kept. It used to be dropped without a word.<\/li>\n<li>Changed (Premium): the templates <code>premium\/proofs.php<\/code> and <code>premium\/proof-thread.php<\/code> have new markup. Copies in a theme need the same changes.<\/li>\n<li>Fixed: uploading from the admin a file whose name had spaces or brackets failed with \"Invalid file name.\"<\/li>\n<li>Fixed: \"Delete attachments\" in the orders list also deleted the files of that order's proofs.<\/li>\n<li>Fixed: \"Delete attachments\" in the orders list could end on a blank page when another plugin handles the bulk actions of that list too.<\/li>\n<li>Fixed (Premium): on a shop that keeps its orders in the classic storage, \"Send email\" in the message form did nothing.<\/li>\n<\/ul>\n\n<h4>1.4.0<\/h4>\n\n<ul>\n<li>New: proofs \/ approval requests (Premium). Send a file from the order for the customer to approve; they approve or reject it on their order page, and you write to each other. A new version asks for approval again and keeps the history: every version, message and answer, dated, in one conversation. Proofs have their own card in the order's Attachments box and their own screen, Attach Me \u2192 Proofs, with what is waiting, rejected and approved across every order.<\/li>\n<li>New: the customer can add files to their answers and messages (Premium, off by default). Number, size and types are set on the new Settings \u2192 Proofs tab, and checked on the server.<\/li>\n<li>New: when the customer may write \u2014 whenever they like, once after each version or message of yours, or only with their answer \u2014 per proof, with a default.<\/li>\n<li>New: reminders when the customer does not answer, and automatic approval after a number of days (Premium). Each reminder is written into the conversation; the customer is told the date before a file is approved for them; both stop as soon as the customer writes back, until you answer.<\/li>\n<li>New: a \"Files to approve\" page in My account (Premium), with how many are waiting in the menu.<\/li>\n<li>New: emails about proofs are grouped: what happens in a few minutes on one order goes out as one email, to the customer or to you. The new version can be attached as well as linked.<\/li>\n<li>New: import from the CodeCanyon \"WooCommerce File Approval\" plugin (Premium), with its conversations, customers' files, answers, settings and preset answers.<\/li>\n<li>New: the answer buttons on the order page \u2014 Approve, Reject, Send message \u2014 each with a colour you can set, following your theme by default.<\/li>\n<li>New: a Suggest a feature page in the menu (Premium).<\/li>\n<li>Changed: customer approval set on an order attachment becomes a proof, automatically: the file is its first version, the customer's answer and comment its verdict, with their dates. Download links already sent keep working.<\/li>\n<li>Changed: the approval settings \u2014 order status, notifications, order notes \u2014 moved to the new Settings \u2192 Proofs tab, and the approval defaults on the Default options tab are now the defaults of a new proof.<\/li>\n<li>Changed: All attachments no longer has the \"waiting for approval\" view, and My Account \u2192 Downloads no longer has its approval column: proofs have their own screen and their own page.<\/li>\n<li>Changed: a CSV row asking for approval creates a proof.<\/li>\n<li>Updated: Freemius SDK 2.13.5.<\/li>\n<\/ul>\n\n<h4>1.3.0<\/h4>\n\n<ul>\n<li>New: each product file can choose its own place on the product page \u2014 in the tab, under the short description or after the \"Add to cart\" button \u2014 or follow the shop default. The same for bulk product attachments (Premium).<\/li>\n<li>New: sections on the product page. Give files a section, such as \"Manuals\", and they are listed together under it; sections can start folded. A new compact list layout, one file per line, beside the existing cards (General \u2192 Product page).<\/li>\n<li>New: a Product attachments block, for a block theme's single product template or any page: the current product's files, or any product's, all of them or only those set to one place.<\/li>\n<li>New: All attachments (Premium). Every order's files on one screen, with search and views for files not downloaded yet, waiting for approval, expiring this week and expired. Delete one file, the ones you tick, or every expired file at once.<\/li>\n<li>New: bulk order attachments (Premium). One file for the orders you pick by number, or for every order, kept once in its rule and shown next to each order's own files and in the emails you choose. Approval, download limits and download history stay with files attached to the order itself.<\/li>\n<li>New: an order and a product now list the bulk attachments that reach them, under their own files, with a link to the rules (Premium).<\/li>\n<li>New: with WPML or Polylang, a bulk attachment's name and description can be written in every language of the shop, one field per language as on the Texts tab (Premium). A language left empty shows the default one.<\/li>\n<li>New: the CSV import (Premium) takes product rows as well as order rows: a product by id or SKU, with optional visibility, position and section columns. A variation gets the file on its parent, for that variation only. Drag the file onto the page; a comma, semicolon or tab separator is recognised on its own, and a sample file can be downloaded.<\/li>\n<li>Changed: \"Bulk product attachments\" and \"Import from CSV\" are now one menu entry, Bulk attachments, with Products, Orders and CSV import tabs (Premium). The old import address leads to its tab.<\/li>\n<li>Improved: on the products list, a paperclip heads the attachments column instead of a word that broke the table.<\/li>\n<li>Improved: an attachment's fields are grouped under small headings \u2014 Content, File, Who sees it and where \u2014 instead of being ruled off one by one, on the order screen, the product screen and the bulk product attachments screen.<\/li>\n<li>Fixed: on the product screen, \"Where the customer sees it\" sat glued to the emails below it.<\/li>\n<li>Developers: each file on the product page is drawn by a new template, product\/attachment.php; product\/tab.php arranges them. A copy of tab.php from an earlier version keeps working.<\/li>\n<\/ul>\n\n<h4>1.2.0<\/h4>\n\n<ul>\n<li>New: each file's type and size under its name on the order page and the product page, as in \"PDF \u00b7 2.4 MB\". On by default; switch it off under General \u2192 How each file is shown.<\/li>\n<li>New: a product's files can sit under the short description or after the \"Add to cart\" button instead of in their own tab (General \u2192 Product page).<\/li>\n<li>New: download history (Premium). See on every order whether the customer has downloaded each file and when, with an order note the first time. The free version already records it, so the history is there whenever you upgrade.<\/li>\n<li>Changed: downloads by the shop's own staff are no longer counted. Opening a customer's link to check a file used to count as a download, and used up one of the customer's downloads on a file with a limit.<\/li>\n<li>Improved: the attachments box on the order screen is three separate sections \u2014 the files, the download links in the order emails, and the message to the customer \u2014 each with its own button. The email block's text and statuses only appear while it is switched on.<\/li>\n<li>Improved: customer approval offers Yes and No only (Premium). A submission with no answer and no comment is ignored, instead of sending the shop a \"Not yet\" note and email.<\/li>\n<li>Fixed: on sites hosted on Windows, an uploaded file was never attached: the upload finished, and the attachment was not created.<\/li>\n<li>Fixed: when saving an attachment failed, the reason is shown instead of \"Something went wrong\".<\/li>\n<li>Fixed: the message to the customer in the orders list's \"Manage\" window had no text editor (Premium).<\/li>\n<\/ul>\n\n<h4>1.1.0<\/h4>\n\n<ul>\n<li>New: Default options tab. Choose the emails, hidden statuses and email block a new attachment starts with, for order attachments, product attachments or both. Premium adds defaults for customer approval, the download terms, the copy-link button and the manual message to the customer. Settings imported from \"WooCommerce Attach Me!\" now include its default options.<\/li>\n<li>New: an attachment's less common settings sit in a collapsible \"Advanced options\" section, and options that depend on another one only appear once it is switched on.<\/li>\n<li>Improved: \"Bulk rules\" is now called \"Bulk product attachments\" (Premium).<\/li>\n<li>Improved: the files offered in the manual message to the customer are switches, and can start all selected, with a confirmation before sending a message with no files (Premium).<\/li>\n<\/ul>\n\n<h4>1.0.1<\/h4>\n\n<ul>\n<li>Fixed: on stores using the classic order storage (HPOS switched off), the importer counted every order as legacy data, showed the import notice on sites that never had the old plugin, and could keep running without finishing.<\/li>\n<li>Fixed: the automatic deletion of expired files (Premium) stopped after the first 200 orders with attachments.<\/li>\n<\/ul>\n\n<h4>1.0.0<\/h4>\n\n<ul>\n<li>First release. A rewrite from scratch of the CodeCanyon \"WooCommerce Attach Me!\" plugin, with an automatic importer for its settings, product attachments and order files.<\/li>\n<li>Uploaded files are served from a protected folder through a signed, access-checked endpoint, always \u2014 not as an option.<\/li>\n<li>Chunked uploads, so the server's per-request limit is not the limit on attachment size.<\/li>\n<li>HPOS support, template overrides, and every customer-facing text editable per language with WPML or Polylang.<\/li>\n<\/ul>","raw_excerpt":"Order and product attachments for WooCommerce: attach files, show them to the customer and send them with the order emails.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/kn.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/366308","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/kn.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/kn.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/kn.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=366308"}],"author":[{"embeddable":true,"href":"https:\/\/kn.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/vanquish83"}],"wp:attachment":[{"href":"https:\/\/kn.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=366308"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/kn.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=366308"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/kn.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=366308"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/kn.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=366308"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/kn.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=366308"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/kn.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=366308"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}