diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml new file mode 100644 index 0000000..4b9e915 --- /dev/null +++ b/.gitea/workflows/release.yml @@ -0,0 +1,205 @@ +name: Create Release Package + +on: + push: + tags: + - 'v*' + +jobs: + build-release: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.3' + extensions: mbstring, xml, zip, intl, gettext + tools: composer:v2 + + - name: Get version from tag + id: version + run: | + VERSION=${GITHUB_REF_NAME#v} + echo "version=$VERSION" >> $GITHUB_OUTPUT + echo "Building version: $VERSION" + + - name: Validate composer.json + run: composer validate --strict + + - name: Install Composer dependencies (production) + run: | + composer config platform.php 8.3.0 + composer install --no-dev --optimize-autoloader --no-interaction + + - name: Install gettext + run: apt-get update && apt-get install -y gettext + + - name: Compile translations + run: | + for po in languages/*.po; do + if [ -f "$po" ]; then + mo="${po%.po}.mo" + echo "Compiling $po to $mo" + msgfmt -o "$mo" "$po" + fi + done + + - name: Verify plugin version matches tag + run: | + PLUGIN_VERSION=$(grep -oP "Version:\s*\K[0-9]+\.[0-9]+\.[0-9]+" wc-composable-product.php | head -1) + TAG_VERSION=${{ steps.version.outputs.version }} + if [ "$PLUGIN_VERSION" != "$TAG_VERSION" ]; then + echo "Error: Plugin version ($PLUGIN_VERSION) does not match tag version ($TAG_VERSION)" + exit 1 + fi + echo "Version verified: $PLUGIN_VERSION" + + - name: Create release directory + run: mkdir -p releases + + - name: Build release package + run: | + VERSION=${{ steps.version.outputs.version }} + PLUGIN_NAME="wc-composable-product" + RELEASE_FILE="releases/${PLUGIN_NAME}-${VERSION}.zip" + + # Move to parent directory for proper zip structure + cd .. + + # Create zip with proper WordPress plugin structure + zip -r "${PLUGIN_NAME}/${RELEASE_FILE}" "${PLUGIN_NAME}" \ + -x "${PLUGIN_NAME}/.git/*" \ + -x "${PLUGIN_NAME}/.gitea/*" \ + -x "${PLUGIN_NAME}/.github/*" \ + -x "${PLUGIN_NAME}/.vscode/*" \ + -x "${PLUGIN_NAME}/.claude/*" \ + -x "${PLUGIN_NAME}/CLAUDE.md" \ + -x "${PLUGIN_NAME}/wp-core" \ + -x "${PLUGIN_NAME}/wp-core/*" \ + -x "${PLUGIN_NAME}/wp-plugins" \ + -x "${PLUGIN_NAME}/wp-plugins/*" \ + -x "${PLUGIN_NAME}/releases/*" \ + -x "${PLUGIN_NAME}/cache/*" \ + -x "${PLUGIN_NAME}/composer.lock" \ + -x "${PLUGIN_NAME}/*.log" \ + -x "${PLUGIN_NAME}/.gitignore" \ + -x "${PLUGIN_NAME}/.editorconfig" \ + -x "${PLUGIN_NAME}/phpcs.xml*" \ + -x "${PLUGIN_NAME}/phpunit.xml*" \ + -x "${PLUGIN_NAME}/tests/*" \ + -x "${PLUGIN_NAME}/*.po~" \ + -x "${PLUGIN_NAME}/*.bak" \ + -x "*.DS_Store" + + cd "${PLUGIN_NAME}" + echo "Created: ${RELEASE_FILE}" + + - name: Generate checksums + run: | + VERSION=${{ steps.version.outputs.version }} + + cd releases + sha256sum "wc-composable-product-${VERSION}.zip" > "wc-composable-product-${VERSION}.zip.sha256" + + echo "SHA256:" + cat "wc-composable-product-${VERSION}.zip.sha256" + + - name: Verify package structure + run: | + set +o pipefail + VERSION=${{ steps.version.outputs.version }} + echo "Package contents:" + unzip -l "releases/wc-composable-product-${VERSION}.zip" | head -50 || true + + # Verify main file is at correct location + if unzip -l "releases/wc-composable-product-${VERSION}.zip" | grep -q "wc-composable-product/wc-composable-product.php"; then + echo "✓ Main plugin file at correct location" + else + echo "✗ Error: Main plugin file not found at wc-composable-product/wc-composable-product.php" + exit 1 + fi + + # Verify vendor directory is included + if unzip -l "releases/wc-composable-product-${VERSION}.zip" | grep -q "wc-composable-product/vendor/"; then + echo "✓ Vendor directory included" + else + echo "✗ Error: Vendor directory not found" + exit 1 + fi + + - name: Extract changelog for release notes + id: changelog + run: | + VERSION=${{ steps.version.outputs.version }} + # Extract changelog section for this version + NOTES=$(sed -n "/^## \[${VERSION}\]/,/^## \[/p" CHANGELOG.md | sed '$ d' | tail -n +2) + if [ -z "$NOTES" ]; then + NOTES="Release version ${VERSION}" + fi + # Save to file for multi-line output + echo "$NOTES" > release_notes.txt + echo "Release notes extracted" + + - name: Create Gitea Release + env: + GITEA_TOKEN: ${{ secrets.SRC_GITEA_TOKEN }} + run: | + VERSION=${{ steps.version.outputs.version }} + TAG_NAME=${{ github.ref_name }} + PRERELEASE="false" + if [[ "$TAG_NAME" == *-* ]]; then + PRERELEASE="true" + fi + + # Read release notes + BODY=$(cat release_notes.txt) + + # Check if release already exists for this tag and delete it + EXISTING_RELEASE=$(curl -s \ + -H "Authorization: token ${GITEA_TOKEN}" \ + "${GITHUB_SERVER_URL}/api/v1/repos/${GITHUB_REPOSITORY}/releases/tags/${TAG_NAME}") + + EXISTING_ID=$(echo "$EXISTING_RELEASE" | jq -r '.id // empty') + + if [ -n "$EXISTING_ID" ] && [ "$EXISTING_ID" != "null" ]; then + echo "Deleting existing release ID: $EXISTING_ID" + curl -s -X DELETE \ + -H "Authorization: token ${GITEA_TOKEN}" \ + "${GITHUB_SERVER_URL}/api/v1/repos/${GITHUB_REPOSITORY}/releases/${EXISTING_ID}" + fi + + # Create release via Gitea API + RELEASE_RESPONSE=$(curl -s -X POST \ + -H "Authorization: token ${GITEA_TOKEN}" \ + -H "Content-Type: application/json" \ + -d "{\"tag_name\": \"${TAG_NAME}\", \"name\": \"Release ${VERSION}\", \"body\": $(echo "$BODY" | jq -Rs .), \"draft\": false, \"prerelease\": ${PRERELEASE}}" \ + "${GITHUB_SERVER_URL}/api/v1/repos/${GITHUB_REPOSITORY}/releases") + + RELEASE_ID=$(echo "$RELEASE_RESPONSE" | jq -r '.id') + + if [ "$RELEASE_ID" == "null" ] || [ -z "$RELEASE_ID" ]; then + echo "Failed to create release:" + echo "$RELEASE_RESPONSE" + exit 1 + fi + + echo "Created release ID: $RELEASE_ID" + + # Upload attachments + for file in "releases/wc-composable-product-${VERSION}.zip" "releases/wc-composable-product-${VERSION}.zip.sha256"; do + if [ -f "$file" ]; then + FILENAME=$(basename "$file") + echo "Uploading $FILENAME..." + curl -s -X POST \ + -H "Authorization: token ${GITEA_TOKEN}" \ + -H "Content-Type: application/octet-stream" \ + --data-binary "@$file" \ + "${GITHUB_SERVER_URL}/api/v1/repos/${GITHUB_REPOSITORY}/releases/${RELEASE_ID}/assets?name=${FILENAME}" + echo "Uploaded $FILENAME" + fi + done + + echo "Release created successfully: ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/releases/tag/${TAG_NAME}" diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 diff --git a/CHANGELOG.md b/CHANGELOG.md index e61be74..cc6f57a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,45 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.2.0] - 2026-03-01 + +### Fixed + +- **CRITICAL**: Product selection always empty regardless of configuration (categories, tags, or SKUs) + - Root cause: Product query used a `meta_query` checking `_product_type` in `wp_postmeta`, but WooCommerce stores product types in the `product_type` **taxonomy** — the `!=` comparison with a non-existent meta key caused an INNER JOIN returning zero results + - Fix: Replaced broken `meta_query` with correct `tax_query` using `product_type` taxonomy to exclude composable products +- **CRITICAL**: Cart price always 0.00 despite correct frontend price calculation + - Root cause: `composable_price_calculated` flag was persisted to the cart session, preventing price recalculation on subsequent page loads — but `set_price()` only modifies the in-memory product object and is lost between requests + - Fix: Removed per-item session flag; the existing static `$already_calculated` flag already prevents duplicate calculation within a single request +- **Admin tab rendering**: Both General and Composable Options panels visible on initial page load + - Root cause: JavaScript manually showed `#composable_product_data` via `.show()` without hiding the General panel + - Fix: Trigger WooCommerce's native tab click instead, so the tab system handles panel visibility correctly + +### Added + +- **Gitea CI/CD release workflow** (`.gitea/workflows/release.yml`) + - Triggered on `v*` tags + - Installs PHP 8.3 with production Composer dependencies + - Compiles `.po` → `.mo` translations + - Verifies plugin version matches tag + - Builds release ZIP with proper WordPress directory structure + - Generates SHA-256 checksums + - Verifies package contains main plugin file and vendor directory + - Extracts changelog for release notes + - Creates Gitea release with attachments via API + +### Removed + +- Debug logging from v1.1.14 (no longer needed after root cause identified) + +### Technical + +- Modified files: includes/Product_Type.php, includes/Cart_Handler.php, assets/js/admin.js +- New file: .gitea/workflows/release.yml +- Product query now correctly uses `tax_query` with `product_type` taxonomy (`NOT IN` operator) +- Cart price recalculated on every request via `woocommerce_before_calculate_totals` hook +- Admin JS uses `$('ul.product_data_tabs li.composable_options a').trigger('click')` for native WooCommerce tab handling + ## [1.1.14] - 2025-12-31 ### Added diff --git a/CLAUDE.md b/CLAUDE.md index b2f1b29..aa1272b 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -255,8 +255,9 @@ unzip -l wc-composable-product-vX.X.X.zip - ✅ ~~Small rendering Bug in admin area. If you load the side, on first view it shows the first both tabs.~~ **FIXED in v1.1.8** - ✅ ~~In the frontend, regardless which selection mode you use, there appears no product selection in any way.~~ **FIXED in v1.1.8** - ✅ ~~The pricing field in the frontend should be rendered as localized price field include currency.~~ **FIXED in v1.1.8** -- Still no product selection in frontend. Current mode 'by Category', but 'by tag' also didn't work -- The tab rendering is still no correct. first both tabs are shown on initial page load. After clicking a tab, they behave as expected. Update: I Think there is a collision with the dynamicly changing the criteria with the related field and the tab switching function. +- ✅ ~~Still no product selection in frontend. Current mode 'by Category', but 'by tag' also didn't work~~ **FIXED in v1.2.0** - Root cause: meta_query checked `_product_type` in postmeta, but WooCommerce stores product types in the `product_type` taxonomy. The `!=` comparison with a non-existent meta key caused INNER JOIN returning zero results. Fixed by using correct `tax_query`. +- ✅ ~~The tab rendering is still no correct. first both tabs are shown on initial page load. After clicking a tab, they behave as expected.~~ **FIXED in v1.2.0** - JS now triggers WooCommerce's native tab click instead of manually toggling panel visibility. +- ✅ ~~Cart price always 0.00 despite correct frontend price calculation~~ **FIXED in v1.2.0** - `composable_price_calculated` session flag prevented price recalculation on subsequent page loads. ## Session History @@ -1883,6 +1884,64 @@ This session demonstrated the importance of changing debugging strategy after mu --- +### v1.2.0 - Critical Bug Fixes & CI/CD (2026-03-01) + +#### Session 15: Root Cause Discovery and Automated Releases + +**Major bug fix release** resolving three long-standing issues that persisted through v1.1.11-v1.1.14. + +**Bugs fixed:** + +1. **Product selection always empty** (the real root cause, finally found!) + - **Root cause**: `includes/Product_Type.php` line 117-124 had a `meta_query` checking `_product_type != 'composable'` in `wp_postmeta`. But WooCommerce stores product types in the `product_type` **taxonomy**, not in postmeta. The `!=` comparison on a non-existent meta key generates an `INNER JOIN` on `wp_postmeta` that matches zero rows — returning no products at all. + - **Fix**: Replaced `meta_query` with correct `tax_query` using `product_type` taxonomy with `NOT IN` operator. + - **Why v1.1.11-v1.1.14 failed**: All previous fix attempts addressed symptoms (variable products, stock filtering, debug logging) but never examined the actual WP_Query construction. The meta_query was the root cause all along. + +2. **Cart price always 0.00** + - **Root cause**: `includes/Cart_Handler.php` stored a `composable_price_calculated` flag in the cart session. On the next page load (cart, checkout), this flag was restored from session and prevented price recalculation — but `set_price()` only modifies the in-memory product object and is lost between requests. + - **Fix**: Removed the per-item `composable_price_calculated` flag entirely. The existing `static $already_calculated` flag already handles the "don't run twice in the same request" concern. + +3. **Admin tab rendering on initial page load** + - **Root cause**: JavaScript called `$('#composable_product_data').show()` which made the composable panel visible without hiding the General panel that WooCommerce shows by default. + - **Fix**: Trigger WooCommerce's native tab click (`$('ul.product_data_tabs li.composable_options a').trigger('click')`) so the tab system handles panel visibility correctly. + +**New feature:** + +4. **Gitea CI/CD release workflow** (`.gitea/workflows/release.yml`) + - Triggered on `v*` tags + - Installs PHP 8.3, Composer deps (production), compiles translations + - Verifies plugin version matches tag + - Builds release ZIP with proper WordPress directory structure + - Generates SHA-256 checksums, verifies package structure + - Creates Gitea release with ZIP and checksum attachments + - Uses `SRC_GITEA_TOKEN` secret for Gitea API + +**Files modified:** + +- includes/Product_Type.php: Replaced `meta_query` with `tax_query`, removed debug logging +- includes/Cart_Handler.php: Removed `composable_price_calculated` session flag +- assets/js/admin.js: Use native WooCommerce tab click instead of manual panel toggle + +**Files created:** + +- .gitea/workflows/release.yml: Gitea CI/CD release workflow + +**Key lessons learned:** + +1. **WooCommerce stores product types in taxonomy, not postmeta**: This is the single most important lesson from the entire v1.1.11-v1.1.14 debugging saga. `_product_type` does NOT exist in `wp_postmeta` — product types are terms in the `product_type` taxonomy. + +2. **WP_Query `!=` on non-existent meta keys returns zero results**: When you use `'compare' => '!='` in a meta_query, WordPress generates an `INNER JOIN` that only matches posts having that meta key. Posts without the key are excluded entirely. + +3. **Don't persist calculation flags in cart sessions**: `set_price()` only modifies in-memory objects. Any flag that prevents recalculation must NOT be stored in session data — use request-scoped variables (like `static`) instead. + +4. **Use native WooCommerce UI mechanisms**: For tab/panel visibility, trigger WooCommerce's own click handlers rather than manually toggling visibility. WooCommerce's tab system handles hiding all other panels automatically. + +5. **Read the actual query, not just the results**: v1.1.11-v1.1.14 all tried to fix what happened AFTER the query (stock filtering, variation expansion, debug logging), but the query itself was the problem. + +**Status:** v1.2.0 released with all three bugs resolved and CI/CD automation added. + +--- + **For AI Assistants:** When starting a new session on this project: diff --git a/README.md b/README.md index 093025e..6305de6 100644 --- a/README.md +++ b/README.md @@ -10,10 +10,13 @@ This plugin adds a new product type to WooCommerce that allows customers to buil - **Custom Product Type**: New "Composable Product" type in WooCommerce - **Flexible Selection**: Define available products by category, tag, or SKU +- **Variable Product Support**: Automatically expands variable products into selectable variations +- **Stock Management**: Real-time stock validation, visual indicators, and automatic inventory tracking - **Configurable Limits**: Set global or per-product selection limits -- **Pricing Options**: Fixed price or sum of selected products -- **Multi-language Support**: Fully translatable with i18n support +- **Pricing Options**: Fixed price or sum of selected products with full locale-aware formatting +- **Multi-language Support**: Fully translated in 6 locales (de_DE, de_CH, fr_CH, it_CH + informal variants) - **Modern UI**: Clean interface built with Twig templates and vanilla JavaScript +- **CI/CD**: Automated release workflow for Gitea ## Requirements @@ -43,6 +46,7 @@ This plugin adds a new product type to WooCommerce that allows customers to buil ### Global Settings Navigate to WooCommerce > Settings > Composable Products to configure: + - Default selection limit - Default pricing mode - Display options @@ -60,10 +64,28 @@ composer install ### Translation Generate POT file: + ```bash wp i18n make-pot . languages/wc-composable-product.pot ``` +Compile translations: + +```bash +for po in languages/*.po; do msgfmt -o "${po%.po}.mo" "$po"; done +``` + +### Creating Releases + +Releases are automated via Gitea CI/CD. Push an annotated tag to trigger: + +```bash +git tag -a v1.2.0 -m "Release v1.2.0" +git push origin v1.2.0 +``` + +The workflow builds the release ZIP, compiles translations, generates checksums, and creates a Gitea release with attachments. + ## License GPL v3 or later - see LICENSE file for details diff --git a/assets/css/admin.css b/assets/css/admin.css old mode 100644 new mode 100755 diff --git a/assets/css/frontend.css b/assets/css/frontend.css old mode 100644 new mode 100755 diff --git a/assets/js/admin.js b/assets/js/admin.js old mode 100644 new mode 100755 index 53b37e4..c4627a1 --- a/assets/js/admin.js +++ b/assets/js/admin.js @@ -17,12 +17,14 @@ if (productType === 'composable') { $('.show_if_composable').show(); $('.hide_if_composable').hide(); - $('#composable_product_data').show(); - $('.product_data_tabs .composable_options a').show(); + // Show the composable tab, then click it so WooCommerce's + // native tab system hides all other panels properly + $('.product_data_tabs li.composable_options').show(); + $('ul.product_data_tabs li.composable_options a').trigger('click'); } else { $('.show_if_composable').hide(); + $('.product_data_tabs li.composable_options').hide(); $('#composable_product_data').hide(); - $('.product_data_tabs .composable_options a').hide(); } }).trigger('change'); diff --git a/assets/js/frontend.js b/assets/js/frontend.js old mode 100644 new mode 100755 diff --git a/includes/Cart_Handler.php b/includes/Cart_Handler.php index 9cac414..d041cc8 100644 --- a/includes/Cart_Handler.php +++ b/includes/Cart_Handler.php @@ -200,7 +200,7 @@ class Cart_Handler { return; } - // Use static flag to prevent multiple executions + // Use static flag to prevent multiple executions within the same request static $already_calculated = false; if ($already_calculated) { return; @@ -208,13 +208,10 @@ class Cart_Handler { foreach ($cart->get_cart() as $cart_item_key => $cart_item) { if (isset($cart_item['data']) && $cart_item['data']->get_type() === 'composable') { - if (isset($cart_item['composable_products']) && !isset($cart_item['composable_price_calculated'])) { + if (isset($cart_item['composable_products'])) { $product = $cart_item['data']; $price = $product->calculate_composed_price($cart_item['composable_products']); $cart_item['data']->set_price($price); - - // Mark as calculated to prevent re-calculation by other plugins - $cart->cart_contents[$cart_item_key]['composable_price_calculated'] = true; } } } diff --git a/includes/Product_Type.php b/includes/Product_Type.php index de2c959..bbba38d 100644 --- a/includes/Product_Type.php +++ b/includes/Product_Type.php @@ -110,24 +110,20 @@ class Product_Type extends \WC_Product { 'post_status' => 'publish', 'orderby' => 'title', 'order' => 'ASC', - 'tax_query' => [], ]; - // Exclude composable products from selection - $args['meta_query'] = [ + // Exclude composable products using the product_type taxonomy + // (WooCommerce stores product types as taxonomy terms, NOT as postmeta) + $args['tax_query'] = [ 'relation' => 'AND', [ - 'key' => '_product_type', - 'value' => 'composable', - 'compare' => '!=', + 'taxonomy' => 'product_type', + 'field' => 'slug', + 'terms' => ['composable'], + 'operator' => 'NOT IN', ], ]; - // Debug logging - if (defined('WP_DEBUG') && WP_DEBUG) { - error_log('Composable Product Criteria: ' . print_r($criteria, true)); - } - switch ($criteria['type']) { case 'category': if (!empty($criteria['categories'])) { @@ -154,28 +150,20 @@ class Product_Type extends \WC_Product { case 'sku': if (!empty($criteria['skus'])) { $skus = array_map('trim', explode(',', $criteria['skus'])); - $args['meta_query'][] = [ - 'key' => '_sku', - 'value' => $skus, - 'compare' => 'IN', + $args['meta_query'] = [ + [ + 'key' => '_sku', + 'value' => $skus, + 'compare' => 'IN', + ], ]; } break; } - // Debug logging - if (defined('WP_DEBUG') && WP_DEBUG) { - error_log('Composable Product Query Args: ' . print_r($args, true)); - } - $query = new \WP_Query($args); $products = []; - // Debug logging - if (defined('WP_DEBUG') && WP_DEBUG) { - error_log('Composable Product Query Found: ' . $query->found_posts . ' posts'); - } - if ($query->have_posts()) { foreach ($query->posts as $post) { $product = wc_get_product($post->ID); @@ -186,36 +174,21 @@ class Product_Type extends \WC_Product { // Handle variable products by including their variations if ($product->is_type('variable')) { - // Get variation IDs directly from the product $variation_ids = $product->get_children(); - if (defined('WP_DEBUG') && WP_DEBUG) { - error_log('Variable product ' . $product->get_id() . ' has ' . count($variation_ids) . ' variations'); - } foreach ($variation_ids as $variation_id) { $variation = wc_get_product($variation_id); if ($variation && $variation->is_purchasable()) { $products[] = $variation; - if (defined('WP_DEBUG') && WP_DEBUG) { - error_log('Added variation ' . $variation_id . ' - ' . $variation->get_name()); - } } } } elseif ($product->is_purchasable()) { - // Simple and other product types $products[] = $product; - if (defined('WP_DEBUG') && WP_DEBUG) { - error_log('Added simple product ' . $product->get_id() . ' - ' . $product->get_name()); - } } } } wp_reset_postdata(); - if (defined('WP_DEBUG') && WP_DEBUG) { - error_log('Total products available: ' . count($products)); - } - return $products; } diff --git a/languages/wc-composable-product-de_CH.mo b/languages/wc-composable-product-de_CH.mo deleted file mode 100644 index c21f432..0000000 Binary files a/languages/wc-composable-product-de_CH.mo and /dev/null differ diff --git a/languages/wc-composable-product-de_CH.po b/languages/wc-composable-product-de_CH.po old mode 100644 new mode 100755 diff --git a/languages/wc-composable-product-de_CH_informal.mo b/languages/wc-composable-product-de_CH_informal.mo deleted file mode 100644 index 1d29937..0000000 Binary files a/languages/wc-composable-product-de_CH_informal.mo and /dev/null differ diff --git a/languages/wc-composable-product-de_CH_informal.po b/languages/wc-composable-product-de_CH_informal.po old mode 100644 new mode 100755 diff --git a/languages/wc-composable-product-de_DE.mo b/languages/wc-composable-product-de_DE.mo deleted file mode 100644 index 9fd77f8..0000000 Binary files a/languages/wc-composable-product-de_DE.mo and /dev/null differ diff --git a/languages/wc-composable-product-de_DE.po b/languages/wc-composable-product-de_DE.po old mode 100644 new mode 100755 diff --git a/languages/wc-composable-product-de_DE_informal.mo b/languages/wc-composable-product-de_DE_informal.mo deleted file mode 100644 index 98f3fe6..0000000 Binary files a/languages/wc-composable-product-de_DE_informal.mo and /dev/null differ diff --git a/languages/wc-composable-product-de_DE_informal.po b/languages/wc-composable-product-de_DE_informal.po old mode 100644 new mode 100755 diff --git a/languages/wc-composable-product-fr_CH.mo b/languages/wc-composable-product-fr_CH.mo deleted file mode 100644 index 931ac0f..0000000 Binary files a/languages/wc-composable-product-fr_CH.mo and /dev/null differ diff --git a/languages/wc-composable-product-fr_CH.po b/languages/wc-composable-product-fr_CH.po old mode 100644 new mode 100755 diff --git a/languages/wc-composable-product-it_CH.mo b/languages/wc-composable-product-it_CH.mo deleted file mode 100644 index a7ef003..0000000 Binary files a/languages/wc-composable-product-it_CH.mo and /dev/null differ diff --git a/languages/wc-composable-product-it_CH.po b/languages/wc-composable-product-it_CH.po old mode 100644 new mode 100755 diff --git a/languages/wc-composable-product.pot b/languages/wc-composable-product.pot old mode 100644 new mode 100755 diff --git a/releases/wc-composable-product-v1.0.0.zip b/releases/wc-composable-product-v1.0.0.zip deleted file mode 100644 index 626139c..0000000 Binary files a/releases/wc-composable-product-v1.0.0.zip and /dev/null differ diff --git a/releases/wc-composable-product-v1.0.0.zip.md5 b/releases/wc-composable-product-v1.0.0.zip.md5 deleted file mode 100644 index 42b517b..0000000 --- a/releases/wc-composable-product-v1.0.0.zip.md5 +++ /dev/null @@ -1 +0,0 @@ -aec3bae001f0013322a73fa941169688 wc-composable-product-v1.0.0.zip diff --git a/releases/wc-composable-product-v1.0.0.zip.sha256 b/releases/wc-composable-product-v1.0.0.zip.sha256 deleted file mode 100644 index d66947c..0000000 --- a/releases/wc-composable-product-v1.0.0.zip.sha256 +++ /dev/null @@ -1 +0,0 @@ -4a0f7ec2171aeabfdfe155419fd6124f35f3e14501ee2ca324bbab447259a8bb wc-composable-product-v1.0.0.zip diff --git a/releases/wc-composable-product-v1.1.0.zip b/releases/wc-composable-product-v1.1.0.zip deleted file mode 100644 index 91744f8..0000000 Binary files a/releases/wc-composable-product-v1.1.0.zip and /dev/null differ diff --git a/releases/wc-composable-product-v1.1.0.zip.md5 b/releases/wc-composable-product-v1.1.0.zip.md5 deleted file mode 100644 index e3a618d..0000000 --- a/releases/wc-composable-product-v1.1.0.zip.md5 +++ /dev/null @@ -1 +0,0 @@ -0a60816bbc5a01c0057c1ffa72679d93 releases/wc-composable-product-v1.1.0.zip diff --git a/releases/wc-composable-product-v1.1.0.zip.sha256 b/releases/wc-composable-product-v1.1.0.zip.sha256 deleted file mode 100644 index 07371f9..0000000 --- a/releases/wc-composable-product-v1.1.0.zip.sha256 +++ /dev/null @@ -1 +0,0 @@ -645fdd68aca95cba77d961f3a48d41b9c12b3d17552572b7c039575dcfcab693 releases/wc-composable-product-v1.1.0.zip diff --git a/releases/wc-composable-product-v1.1.1.zip b/releases/wc-composable-product-v1.1.1.zip deleted file mode 100644 index e092633..0000000 Binary files a/releases/wc-composable-product-v1.1.1.zip and /dev/null differ diff --git a/releases/wc-composable-product-v1.1.1.zip.md5 b/releases/wc-composable-product-v1.1.1.zip.md5 deleted file mode 100644 index d8a3e58..0000000 --- a/releases/wc-composable-product-v1.1.1.zip.md5 +++ /dev/null @@ -1 +0,0 @@ -db09928aea6fffbf9c2e754d2264f2bc wc-composable-product-v1.1.1.zip diff --git a/releases/wc-composable-product-v1.1.1.zip.sha256 b/releases/wc-composable-product-v1.1.1.zip.sha256 deleted file mode 100644 index c6b1631..0000000 --- a/releases/wc-composable-product-v1.1.1.zip.sha256 +++ /dev/null @@ -1 +0,0 @@ -761eef69da910ecfdb20ceeed70b5d0381c7cab895e81a040d132cb0f88d749b wc-composable-product-v1.1.1.zip diff --git a/releases/wc-composable-product-v1.1.10.zip b/releases/wc-composable-product-v1.1.10.zip deleted file mode 100644 index 251b23b..0000000 Binary files a/releases/wc-composable-product-v1.1.10.zip and /dev/null differ diff --git a/releases/wc-composable-product-v1.1.10.zip.md5 b/releases/wc-composable-product-v1.1.10.zip.md5 deleted file mode 100644 index 47e717c..0000000 --- a/releases/wc-composable-product-v1.1.10.zip.md5 +++ /dev/null @@ -1 +0,0 @@ -271aad47684ee8318a8824861d5fc387 wc-composable-product-v1.1.10.zip diff --git a/releases/wc-composable-product-v1.1.10.zip.sha256 b/releases/wc-composable-product-v1.1.10.zip.sha256 deleted file mode 100644 index 477d871..0000000 --- a/releases/wc-composable-product-v1.1.10.zip.sha256 +++ /dev/null @@ -1 +0,0 @@ -63bfe97aa9fd98e74750786ed0e1579b069505e85558316f7042787994c856ac wc-composable-product-v1.1.10.zip diff --git a/releases/wc-composable-product-v1.1.11.zip b/releases/wc-composable-product-v1.1.11.zip deleted file mode 100644 index a177636..0000000 Binary files a/releases/wc-composable-product-v1.1.11.zip and /dev/null differ diff --git a/releases/wc-composable-product-v1.1.11.zip.md5 b/releases/wc-composable-product-v1.1.11.zip.md5 deleted file mode 100644 index 5bbc39f..0000000 --- a/releases/wc-composable-product-v1.1.11.zip.md5 +++ /dev/null @@ -1 +0,0 @@ -63b105311dc1cc8ac67c05528ad02e30 wc-composable-product-v1.1.11.zip diff --git a/releases/wc-composable-product-v1.1.11.zip.sha256 b/releases/wc-composable-product-v1.1.11.zip.sha256 deleted file mode 100644 index ab549a6..0000000 --- a/releases/wc-composable-product-v1.1.11.zip.sha256 +++ /dev/null @@ -1 +0,0 @@ -214002a28a0426b4d2423f234d1dff63e4a8e58c6301cbd6eaed8db670db88c6 wc-composable-product-v1.1.11.zip diff --git a/releases/wc-composable-product-v1.1.12.zip b/releases/wc-composable-product-v1.1.12.zip deleted file mode 100644 index 0584aef..0000000 Binary files a/releases/wc-composable-product-v1.1.12.zip and /dev/null differ diff --git a/releases/wc-composable-product-v1.1.12.zip.md5 b/releases/wc-composable-product-v1.1.12.zip.md5 deleted file mode 100644 index 26f9bfb..0000000 --- a/releases/wc-composable-product-v1.1.12.zip.md5 +++ /dev/null @@ -1 +0,0 @@ -546b9f9dd4ef0ec174d574af301a7bbc wc-composable-product-v1.1.12.zip diff --git a/releases/wc-composable-product-v1.1.12.zip.sha256 b/releases/wc-composable-product-v1.1.12.zip.sha256 deleted file mode 100644 index 298dcc6..0000000 --- a/releases/wc-composable-product-v1.1.12.zip.sha256 +++ /dev/null @@ -1 +0,0 @@ -c445f1744d28cb53ef314f2dbb253aae31a7750f49f615f5c11a109274736f75 wc-composable-product-v1.1.12.zip diff --git a/releases/wc-composable-product-v1.1.13.zip b/releases/wc-composable-product-v1.1.13.zip deleted file mode 100644 index b75d40e..0000000 Binary files a/releases/wc-composable-product-v1.1.13.zip and /dev/null differ diff --git a/releases/wc-composable-product-v1.1.13.zip.md5 b/releases/wc-composable-product-v1.1.13.zip.md5 deleted file mode 100644 index f4d7051..0000000 --- a/releases/wc-composable-product-v1.1.13.zip.md5 +++ /dev/null @@ -1 +0,0 @@ -49d0e5220e927a3b20c25ed5d475f72b wc-composable-product-v1.1.13.zip diff --git a/releases/wc-composable-product-v1.1.13.zip.sha256 b/releases/wc-composable-product-v1.1.13.zip.sha256 deleted file mode 100644 index c6b389a..0000000 --- a/releases/wc-composable-product-v1.1.13.zip.sha256 +++ /dev/null @@ -1 +0,0 @@ -6011f23f19da9c61c1953f9de110d073bb594fa5e75bf9745d37f666e2869873 wc-composable-product-v1.1.13.zip diff --git a/releases/wc-composable-product-v1.1.14.zip b/releases/wc-composable-product-v1.1.14.zip deleted file mode 100644 index 1d93a96..0000000 Binary files a/releases/wc-composable-product-v1.1.14.zip and /dev/null differ diff --git a/releases/wc-composable-product-v1.1.14.zip.md5 b/releases/wc-composable-product-v1.1.14.zip.md5 deleted file mode 100644 index 4c3d180..0000000 --- a/releases/wc-composable-product-v1.1.14.zip.md5 +++ /dev/null @@ -1 +0,0 @@ -7b8bbd9c1e0a5db59f89ae677f095430 wc-composable-product-v1.1.14.zip diff --git a/releases/wc-composable-product-v1.1.14.zip.sha256 b/releases/wc-composable-product-v1.1.14.zip.sha256 deleted file mode 100644 index 839246c..0000000 --- a/releases/wc-composable-product-v1.1.14.zip.sha256 +++ /dev/null @@ -1 +0,0 @@ -7c943fc5a85d5a48125aaf9f2e42434b370c4fa168ca33cd1e3485deb55302a5 wc-composable-product-v1.1.14.zip diff --git a/releases/wc-composable-product-v1.1.2.zip b/releases/wc-composable-product-v1.1.2.zip deleted file mode 100644 index 7845058..0000000 Binary files a/releases/wc-composable-product-v1.1.2.zip and /dev/null differ diff --git a/releases/wc-composable-product-v1.1.2.zip.md5 b/releases/wc-composable-product-v1.1.2.zip.md5 deleted file mode 100644 index a98fcf5..0000000 --- a/releases/wc-composable-product-v1.1.2.zip.md5 +++ /dev/null @@ -1 +0,0 @@ -37cef191778b448dcbd2ae10141f64c6 wc-composable-product-v1.1.2.zip diff --git a/releases/wc-composable-product-v1.1.2.zip.sha256 b/releases/wc-composable-product-v1.1.2.zip.sha256 deleted file mode 100644 index 0b5bfff..0000000 --- a/releases/wc-composable-product-v1.1.2.zip.sha256 +++ /dev/null @@ -1 +0,0 @@ -191eae035b34ce8b33b90cf9d85ed54e493c1b471cda0efe5c992a512e91cc36 wc-composable-product-v1.1.2.zip diff --git a/releases/wc-composable-product-v1.1.3.zip b/releases/wc-composable-product-v1.1.3.zip deleted file mode 100644 index c0b58c0..0000000 Binary files a/releases/wc-composable-product-v1.1.3.zip and /dev/null differ diff --git a/releases/wc-composable-product-v1.1.3.zip.md5 b/releases/wc-composable-product-v1.1.3.zip.md5 deleted file mode 100644 index 87f7d3e..0000000 --- a/releases/wc-composable-product-v1.1.3.zip.md5 +++ /dev/null @@ -1 +0,0 @@ -9bbed416019a796b4d4a5ef72e016e1f wc-composable-product-v1.1.3.zip diff --git a/releases/wc-composable-product-v1.1.3.zip.sha256 b/releases/wc-composable-product-v1.1.3.zip.sha256 deleted file mode 100644 index 2fcf47a..0000000 --- a/releases/wc-composable-product-v1.1.3.zip.sha256 +++ /dev/null @@ -1 +0,0 @@ -0ca23ca12570f0e9c518514ffc5209d78c76c3295954d10ec74a28013a762956 wc-composable-product-v1.1.3.zip diff --git a/releases/wc-composable-product-v1.1.6.zip b/releases/wc-composable-product-v1.1.6.zip deleted file mode 100644 index dd4a6a8..0000000 Binary files a/releases/wc-composable-product-v1.1.6.zip and /dev/null differ diff --git a/releases/wc-composable-product-v1.1.6.zip.md5 b/releases/wc-composable-product-v1.1.6.zip.md5 deleted file mode 100644 index 6cc8983..0000000 --- a/releases/wc-composable-product-v1.1.6.zip.md5 +++ /dev/null @@ -1 +0,0 @@ -eae384e342450abd4ac83af0266ac764 wc-composable-product-v1.1.6.zip diff --git a/releases/wc-composable-product-v1.1.6.zip.sha256 b/releases/wc-composable-product-v1.1.6.zip.sha256 deleted file mode 100644 index e48d8ea..0000000 --- a/releases/wc-composable-product-v1.1.6.zip.sha256 +++ /dev/null @@ -1 +0,0 @@ -d64f4f5f1a00d392989cb613780e5726106a08c6aace08e0c74c80553a0b0f1e wc-composable-product-v1.1.6.zip diff --git a/releases/wc-composable-product-v1.1.7.zip b/releases/wc-composable-product-v1.1.7.zip deleted file mode 100644 index 28fb3b2..0000000 Binary files a/releases/wc-composable-product-v1.1.7.zip and /dev/null differ diff --git a/releases/wc-composable-product-v1.1.7.zip.md5 b/releases/wc-composable-product-v1.1.7.zip.md5 deleted file mode 100644 index 8cbaafa..0000000 --- a/releases/wc-composable-product-v1.1.7.zip.md5 +++ /dev/null @@ -1 +0,0 @@ -871fbb3b910380c0e43bcf1538408eda releases/wc-composable-product-v1.1.7.zip diff --git a/releases/wc-composable-product-v1.1.7.zip.sha256 b/releases/wc-composable-product-v1.1.7.zip.sha256 deleted file mode 100644 index 898cd3c..0000000 --- a/releases/wc-composable-product-v1.1.7.zip.sha256 +++ /dev/null @@ -1 +0,0 @@ -866e7dd34431f4c881629fd8b59ddd3a27c7a45b7324a3d88cd064a3e01c1b83 releases/wc-composable-product-v1.1.7.zip diff --git a/releases/wc-composable-product-v1.1.8.zip b/releases/wc-composable-product-v1.1.8.zip deleted file mode 100644 index 0ecd244..0000000 Binary files a/releases/wc-composable-product-v1.1.8.zip and /dev/null differ diff --git a/releases/wc-composable-product-v1.1.8.zip.md5 b/releases/wc-composable-product-v1.1.8.zip.md5 deleted file mode 100644 index f2f25e3..0000000 --- a/releases/wc-composable-product-v1.1.8.zip.md5 +++ /dev/null @@ -1 +0,0 @@ -78eee5eee4762c308c5d37d1aac06b04 wc-composable-product-v1.1.8.zip diff --git a/releases/wc-composable-product-v1.1.8.zip.sha256 b/releases/wc-composable-product-v1.1.8.zip.sha256 deleted file mode 100644 index 530ca7b..0000000 --- a/releases/wc-composable-product-v1.1.8.zip.sha256 +++ /dev/null @@ -1 +0,0 @@ -d7d06e2a5d336609249f803b681cdf270dbe60d6fc28bdd6c451c6744d2fdab6 wc-composable-product-v1.1.8.zip diff --git a/releases/wc-composable-product-v1.1.9.zip b/releases/wc-composable-product-v1.1.9.zip deleted file mode 100644 index b40d886..0000000 Binary files a/releases/wc-composable-product-v1.1.9.zip and /dev/null differ diff --git a/releases/wc-composable-product-v1.1.9.zip.md5 b/releases/wc-composable-product-v1.1.9.zip.md5 deleted file mode 100644 index 178d5b7..0000000 --- a/releases/wc-composable-product-v1.1.9.zip.md5 +++ /dev/null @@ -1 +0,0 @@ -a5b08f3613d1b1e8aba0c2b7b82a1582 wc-composable-product-v1.1.9.zip diff --git a/releases/wc-composable-product-v1.1.9.zip.sha256 b/releases/wc-composable-product-v1.1.9.zip.sha256 deleted file mode 100644 index 8a8dbd9..0000000 --- a/releases/wc-composable-product-v1.1.9.zip.sha256 +++ /dev/null @@ -1 +0,0 @@ -f9fc497c0531c7ea828e164137f3db6e0a2755b899690dfb7d6411baf0c7a65a wc-composable-product-v1.1.9.zip diff --git a/templates/product-selector.twig b/templates/product-selector.twig old mode 100644 new mode 100755 diff --git a/wc-composable-product.php b/wc-composable-product.php index ed36751..df198f2 100644 --- a/wc-composable-product.php +++ b/wc-composable-product.php @@ -4,7 +4,7 @@ * Plugin Name: WooCommerce Composable Products * Plugin URI: https://src.bundespruefstelle.ch/magdev/wc-composable-product * Description: Create composable products where customers select a limited number of items from a configurable set - * Version: 1.1.14 + * Version: 1.2.0 * Author: Marco Graetsch * Author URI: https://src.bundespruefstelle.ch/magdev * License: GPL v3 or later @@ -20,7 +20,7 @@ defined('ABSPATH') || exit; // Define plugin constants -define('WC_COMPOSABLE_PRODUCT_VERSION', '1.1.14'); +define('WC_COMPOSABLE_PRODUCT_VERSION', '1.2.0'); define('WC_COMPOSABLE_PRODUCT_FILE', __FILE__); define('WC_COMPOSABLE_PRODUCT_PATH', plugin_dir_path(__FILE__)); define('WC_COMPOSABLE_PRODUCT_URL', plugin_dir_url(__FILE__));