Shopify API from PHP: problem with linked metafields in a productCreate call

I’m trying to create a productCreate mutation which specifies the available colours for the product, but I’m getting the error ‘The ‘shopify.color-pattern’ metafield has no values and none were passed in for this linked option’.

I’m passing in variables as follows (closing brackets elided) which are then json-encoded.

[variables] => stdClass Object
(
[product] => stdClass Object
(
[title] => Herring Sittaford Chelsea boots
[productOptions] => Array
(
[0] => stdClass Object
(
[name] => Color
[position] => 1
[linkedMetafield] => stdClass Object
(
[key] => color-pattern
[namespace] => shopify
)

[values] => Array
(
[0] => stdClass Object
(
[linkedMetafieldValue] => gid://shopify/Metaobject/169330016585
[name] => Caramel Suede
)

[1] => stdClass Object
(
[linkedMetafieldValue] => gid://shopify/Metaobject/169330049353
[name] => Honey Suede
)

[2] => stdClass Object
(
[linkedMetafieldValue] => gid://shopify/Metaobject/169330114889
[name] => Ocean Suede
)

[3] => stdClass Object
(
[linkedMetafieldValue] => gid://shopify/Metaobject/169330606409
[name] => Olive Suede
)

[4] => stdClass Object
(
[linkedMetafieldValue] => gid://shopify/Metaobject/169330639177
[name] => Sand Suede
)

[5] => stdClass Object
(
[linkedMetafieldValue] => gid://shopify/Metaobject/169330671945
[name] => Wheat Nubuck
)

The shopify dox are not helpful on this. I’ve tried various tweaks on this and nothing helps. Pass in values as an array on the linkedMetafieldobject and I get ‘Cannot specify ‘values’ for an option linked to a metafield’.

This works if I don’t use linked metafields, but I want this to be nailed down to the defined colours we’ve set up programmatically, I don’t want duplicates.

Anyone got any suggestions?

Thanks in advance,

G

Database Connection Hostinger [closed]

Does anyone know how to live host a website on Hostinger? I’m having trouble connecting my database to my system—it’s preventing user registration and login from working. Can someone please share an example of a login and registration system (with database connection) that works on Hostinger?

Why does WooCommerce still show the old review count after deleting reviews in the WordPress admin?

I’m working on a WooCommerce store, and I’ve deleted all product reviews from the WordPress admin (including emptying the trash). However, the product page still displays the old review count and average rating.

rating.php

<?php
/**
 * Single Product Rating
 *
 * This template can be overridden by copying it to yourtheme/woocommerce/single-product/rating.php.
 *
 * HOWEVER, on occasion WooCommerce will need to update template files and you
 * (the theme developer) will need to copy the new files to your theme to
 * maintain compatibility. We try to do this as little as possible, but it does
 * happen. When this occurs the version of the template file will be bumped and
 * the readme will list any important changes.
 *
 * @see     https://woocommerce.com/document/template-structure/
 * @package WooCommerceTemplates
 * @version 3.6.0
 */

if ( ! defined( 'ABSPATH' ) ) {
    exit; // Exit if accessed directly.
}

global $product;

if ( ! wc_review_ratings_enabled() ) {
    return;
}

$rating_count = $product->get_rating_count();
$review_count = $product->get_review_count();
$average      = $product->get_average_rating();

if ( $rating_count > 0 ) : ?>
    <div class="woocommerce-rating-debug">
        <p>Rating Count: <?php echo esc_html( $rating_count ); ?></p>
        <p>Review Count: <?php echo esc_html( $review_count ); ?></p>
        <p>Average Rating: <?php echo esc_html( $average ); ?></p>
    </div>

    <div class="woocommerce-product-rating">
        <?php echo wc_get_rating_html( $average, $rating_count ); // WPCS: XSS ok. ?>
        <?php if ( comments_open() ) : ?>
            <?php //phpcs:disable ?>
            <a href="#reviews" class="woocommerce-review-link" rel="nofollow">(<?php printf( _n( '%s customer review', '%s customer reviews', $review_count, 'woocommerce' ), '<span class="count">' . esc_html( $review_count ) . '</span>' ); ?>)</a>
            <?php // phpcs:enable ?>
        <?php endif ?>
    </div>

<?php endif; ?>

Getting results like this even after deleting all reviews and ratings.

enter image description here

Even the product detail page in the admin shows “No comments yet.”

enter image description here

How can I force WooCommerce to fully refresh the product review data to reflect zero reviews?

Any help or insight is appreciated.

WordPress sorting filter brings me back to the homepage

I´m making a WordPress website and I want to have a filter on mine search.php file. But whenever I select an option, he brings me back to my homepage instead of being on the same file. I think it has something to do with my url. On the page with the filter, I already have a ?s= in my url. I don’t know how I can fix this in my code that my url has after the ?s= also /?sort=. I don’t if this is even possible, I’m still new to coding.
This is my code (sorry for the ducth words 😉 )

<form method="get" action="<?php echo esc_url(home_url('/')); ?>" class="sortering-form">
   <label for="sortering">Sorteer op:</label>
   <select name="sort" id="sortering" onchange="this.form.submit()">
      <option value="nieuw" <?php selected($_GET['sort'] ?? '', 'nieuw'); ?>>Nieuw → Oud</option>
      <option value="oud" <?php selected($_GET['sort'] ?? '', 'oud'); ?>>Oud → Nieuw</option>
      <option value="titel" <?php selected($_GET['sort'] ?? '', 'titel'); ?>>Titel A → Z</option>
      <option value="random" <?php selected($_GET['sort'] ?? '', 'random'); ?>>Willekeurig</option>
   </select>
</form>

How to use php to calculate the cost of an order? [closed]

I am trying to create a canteen order calculator without using MySQL (project spec, not in my control). The idea is that a user enters some values into the html table and then receives the calculated total cost of their order. Most other ways I’ve tried resulted in fatal errors. This solution is only marginally better, always outputting a cost of $0. Does anyone know why it’s doing that, and how I could fix it? (also new user here, hope I’m asking this right).

<?php
if
(   
    isset($_POST['rolls']) 
    or isset($_POST['pies']) 
    or isset($_POST['crosses']) 
    or isset($_POST['chickens']) 
    or isset($_POST['pastas']) 
    or isset($_POST['milks']) 
    or isset($_POST['juices']) 
    or isset($_POST['waters']) 
)
{
    $finalcost=floatval(0);
    $rolls=0.00;
    $pies=0.00;
    $crosses=0.00;
    $pastas=0.00;
    $chickens=0.00;
    $milks=0.00;
    $juices=0.00;
    $waters=0.00;
    
    function pricefixer ($a,$b)
    {
        switch($b) # find which post to look at. 
        {
            case 'rolls':
            $c=$_POST['rolls'];
            break;
            case 'crosses':
            $c=$_POST['crosses'];
            break;
            case 'chickens':
            $c=$_POST['chickens'];
            break;
            case 'pastas':
            $c=$_POST['pastas'];
            break;
            case 'juices':
            $c=$_POST['juices'];
            break;
            case 'pies':
            $c=$_POST['pies'];
            break;
            case 'milks':
            $c=$_POST['milks'];
            break;
            case 'waters':
            $c=$_POST['waters'];
            break;
            default:
            $c=0;
            break;
            
        }
        
        if($c>0)
        {   
            $a+=$c;
            $a==floatval($a); #Decimal/float prices need decimal/float multipliers. 
        }
    }
    
    function priceadder ($a, $b)
    {
        
        for ($x=0; $x<$a; $x++)
        {
            $finalcost+=$b;
        }
    }
    #simplifes calculation code later

    $order=1; #used to check if user has ordered
    
    #See function pricefixer above
    pricefixer($rolls, 'rolls');
    pricefixer($pies, 'pies');
    pricefixer($chickens, 'chickens');
    pricefixer($pastas, 'pastas');
    pricefixer($crosses, 'crosses');
    pricefixer($milks, 'milks');
    pricefixer($waters, 'waters');
    pricefixer($juices, 'juices');
    
    #Calculate cost
    priceadder($rolls, 4.50);
    priceadder($pies, 2.50);
    priceadder($crosses, 5.00);
    priceadder($chickens, 7.00);
    priceadder($pastas, 6.30);
    priceadder($milks, 3.50);
    priceadder($juices, 3.00);
    priceadder($waters, 2.50);
}
else
{
    $order=0;
}
?>
<html>
<head>
<!-- For when stylehseet is made: <link rel="stylesheet" href="[stylesheet_name_here].css" -->
<meta charset="utf-8">
<title>Canteen Menu</title>
</head>
<body>
<table width=<?php echo $wide; ?> height=<?php echo $tall; ?> border="1" align="center">
    <tr>
        <td colspan="6" align="center" height="15%"> <h2> <b> Hello <?php echo "$given"." "."$surname" ?>, welcome to Narrabundah College online shop. </h2> </b> 
        <br> You are signed in as:<?php echo "$user" ?>. <br> Today's date is <?php echo"$date"; ?>. </td>
    </tr>
    <tr>
        <td rowspan="4" align="center" width="15%"> 
        <a href="canteen_menu.php"> Canteen Data </a> <br>
        <a href="customers_menu.php"> Customer Data </a> <br>
        <a href="stationery_menu.php"> Stationery Data </a> <br>
        <a href="logout.php"> Log Out </a> <br>
        </td>
    </tr>
    <tr>
        <td rowspan="4" colspan="4" align="center"> 
        <!-- Table for easy fo alignment and readability for user -->
        <?php
        if ($order==0)
        {
        ?>
        <table border="1">
        <tr>
        <td colspan="2">
        <h3> Welcome To The Canteen </h3>
        </td>
        </tr>
        <tr>
        <td>
        Items Currentely Avalible:
        <ul align="left">
            <li> Sausage Roll ($4.50) </li>
            <li> Beef and Mushroom Pie ($6.50) </li>
            <li> Almond Crossaint ($5.00) </li>
            <li> Satay Chicken and Rice [conatins peanuts] ($7.00)</li>
            <li> Spaghetti Bolognese ($6.30) </li>
            <li> Chocolate Milk ($3.50) </li>
            <li> Sparkling Raspberry Juice ($3.00) </li>
            <li> PUMP Water ($2.50) </li>
        </ul>
        </td>
        <td>
        Order Quantities: <br> <br>
        <form action="<?php $self ?>" method="post">
        <ul style="list-style-type:none;"> <!-- Removes bullets, list assists in formatting -->
        <li> <input type="number" name="rolls">  </li>
        <li> <input type="number" name="pies">  </li>
        <li> <input type="number" name="crosses">  </li>
        <li> <input type="number" name="chickens">  </li>
        <li> <input type="number" name="pastas">  </li>
        <li><input type="number"  name="milks"> </li>
        <li> <input type="number" name="juices"> </li>
        <li> <input type="number" name="waters"> </li>
        </ul>
        <input type="submit" value="Submit" align="center">
        </form>
        </tr>
        </table>
        </td>
        <?php
        }
        if ($order==1)
        {
            echo 'That order comes to $'.$finalcost.'.';
        }
        ?>
    </tr>
</table>
</body>
</html>

GA4 custom event parameter not available after 96+ hours (despite working setup)

I’m using GA4 in a production web app and sending a custom event using this code:

gtag('event', 'Email sent', {
  email_sent_count: 1,
  email_template: emailTemplate,
})

emailTemplate is a simple string like ‘welcome_email’, ‘reminder’, etc.

The event Email sent shows up in the GA4 Events report

Both parameters (email_sent_count and email_template) appear in DebugView

I’ve tried creating a custom dimension/metric manually in GA4 (Admin > Custom Definitions), but the parameters are not listed even after 96+ hours

Additional context:

I already track 34 other events in GA4, all with custom parameters, and they propagate fine

  • I’ve kept email_template values clean and predictable — no spaces, special characters, or dynamic variations like “Unknown (id)”

  • Property limits are not exceeded (I’m under 50 custom dimensions/metrics)

When I click the “Create custom dimension” button, the email_template parameter from the Email sent event does not appear in the list.

Is there any reason why this specific parameter is delayed or silently dropped?
Has anyone encountered a situation where GA4 delays propagation of new event parameters despite correct setup?

Any help or insights appreciated.

Preconnect/dns-prefetch Firebase Auth

I’m looking into optimizing Firebase Auth.

The web SDK does cache login state, but (unlike the native iOS and Android versions of the SDK) always performs at least one request to check authentication. This causes calls to FB Database (and I assume Firestore) to be delayed until auth has settled. On a good connection, the request(s, preflights included) can take up to 1 second, which isn’t ideal to begin with, but on bad/spotty connections, it’s a lot worse.

So I figured I’d use preconnect and (and dns-prefetch for optionals), but I can’t get it to work.

I’m seeing requests to the following domains:

[1] Performs preflight request
[2] Only requested when security token is no longer valid?

It looks like these are cross origin requests, so the html snippets should end up looking like this:

<link rel="preconnect" href="https://identitytoolkit.googleapis.com" crossorigin>
<link rel="preconnect" href="https://securetoken.googleapis.com" crossorigin>

But this doesn’t seem to work. What am I doing wrong?

Bonus question:

For Firebase Database, is there a way to dns-prefetch the domain for the websocket connection? (I know preconnect doesn’t work for websocket), e.g.:

<link rel="dns-prefetch" href="https://my-app.firebaseio.com">

Should that work?

Outlook Add-In 3rd party authorization

I develop Outlook add-in that should be able to send data to my server. To do this I added authorization flow using Auth0 (same as I do in frontend app)

I am not sure if this approach will pass add-in review for publishing on the marketplace

  1. Is it ok to store access-token in localstorage? If not, what approach to use?
  2. Where to store subscription key I use for Auth0?

I would be grateful for any code examples or links to documentation that demonstrate a secure, third-party authentication flow (specifically with Auth0) for an Office Add-in that would be compliant with AppSource policies.

How to check if an array has consecutive values in any order ? for example in a roll of 41423, we have 1234

I want to build an algorithm that checks if an array has four consecutive values in any order to do something. And when all the elements in that array have consecutive values in any order to do something else.

When the first condition is true I want to leave the order condition disabled.
Here is an example of what I have already done, but, I still can not get the required result.

function checkForStraights(arr) {
  const newArr = arr.toSorted((a, b) => a - b)

  for(let i = 1; i < newArr.slice(0, 4).length; i++){
    if(newArr[i] - newArr[i-1] === 1){
      updateRadioOption(3, 30);
      scoreInputs[4].disabled = false;
    }
    updateRadioOption(5, 0);
  }
  
  for(let i = 1; i< newArr.length; i++){
    if(newArr[i] - newArr[i-1] === 1){
      updateRadioOption(4, 40);
    }
    updateRadioOption(5, 0);
  }
}

How can I use Cypress to retrieve an array of elements, then run a test against each of those elements?

I have a large menu on my site. I want to create a test that test’s each link individually in it’s own it function.

I imagined doing it in the following way:

let linkArr = [];
describe('I am on desktop view of a page to check the main menu links', () => {
    before(() => {
        cy.visit(pageUrl);
        cy.get('.main-header a').each(($link) => {
            linkArr.push($link);
        })
    });

    linkArr.forEach(link => {
        it(`Ensures the link works`, () => {
            checkLink(link);
            const linkText = (link.prop('text').replace("/n", "")).trim();
            stepReportNotes(reportObj, testName, `${link.prop('href')} on '${linkText}' returns 200 or 301`);
        });
    });
});

But its doesn’t. The forEach loop seems to run at the same time as the before() function so the linkArr is empty.

It does kind of work if I wrap the forEach within the it eg:

it(`Ensures each link works`, () => {
    linkArr.forEach(link => {
        checkLink(link);
        const linkText = (link.prop('text').replace("/n", "")).trim();
        stepReportNotes(reportObj, testName, `${link.prop('href')} on '${linkText}' returns 200 or 301`);
    });
});

but then I’m really only running one step and if one link fails that entire step fails.

I’ve tried a few things like creating 2 tests (one to get the array, one to run the test) and moving the loop into a function but with no success.

Would anyone know how to achieve this?

What is causing this CSS cube to “clip” when rotated three-dimensionally?

I have a three dimensional cube that I created in HTML and CSS and can rotate with javascript. It works just about how I expected and I’m pretty happy with it but there’s one problem I just don’t understand: each side of the cube is its own div, and some of them seem to “clip” when rotated in a certain way. Here’s a codepen that shows how it works – you rotate the cube using the arrow keys (it rotates up and down around the x-axis using the up and down keys and left and right around the y-axis using the left and right keys – each keypress advances it 45 degrees in the given direction. Hitting the “R” key will reset it to its original position):

https://codepen.io/shaundgrey/pen/azOjYxx

I removed the initial code snippet because when embedded in the post the issue doesn’t replicate. You’ll have to use the codepen link, I’m sorry. The other two snippets are still embedded below, however.

The easiest way to replicate the problem is to just hit the down key once – you should be able to see that the top and bottom faces (red and green, respectively) seem to “recede” by almost a quarter of their length and the inside of the cube gets exposed.

At first I thought this was a problem with just like, my computer not being fast enough and some of the faces not applying their transformations quickly enough but it doesn’t matter how slow it goes, or even if it stops, the problem is still apparent.

Then I thought maybe it was something to do with the code having a bug in it, since I had basically pasted it together from several different sources and I didn’t fully understand how it worked, but I went through line-by-line and simplified it down to its barest essence and the problem remains unchanged – I learned a lot about the code at least, although exactly what the matrix transformation is doing is still beyond me.

I eventually started removing faces in order to just isolate the problem and that actually got me somewhere – if I just set the visibility of every face except for the top and bottom to “hidden” and hit the down key once, the problem disappears!

https://codepen.io/shaundgrey/pen/NPqLNaV

//the cube and its six faces for easy refernce
var cube = document.querySelector(".cube");
var frontFace = document.querySelector(".cube-face-front");
var backFace = document.querySelector(".cube-face-back");
var leftFace = document.querySelector(".cube-face-left");
var rightFace = document.querySelector(".cube-face-right");
var topFace = document.querySelector(".cube-face-top");
var bottomFace = document.querySelector(".cube-face-bottom");

//this is the rotation matrix in which we can save the current state of the cube
var resetMatrix = new DOMMatrix();
var matrix = new DOMMatrix();

//takes a vector (rotation axis) and angle (rotation direction) as input and rotates the cube accordingly
function applyRotation(x, y, z, angle) {
  var newMatrix = new DOMMatrix().rotateAxisAngle(x, y, z, angle).multiply(matrix);
  cube.style.transform = newMatrix;
  matrix = newMatrix;
}

//takes a keyboard arrow input and creates a vector (rotation axis) and angle (rotation direction) in response, then feeds that vector and angle to applyRotation
function keyboardTurn(event) {
  switch (event.key) {
    case "ArrowRight":
      applyRotation(0, 1, 0, 45);
      break;
    case "ArrowLeft":
      applyRotation(0, 1, 0, -45);
      break;
    case "ArrowUp":
      applyRotation(1, 0, 0, 45);
      break;
    case "ArrowDown":
      applyRotation(1, 0, 0, -45);
      break;
    case "r":
      cube.style.transform = resetMatrix;
      matrix = resetMatrix;
      break;
    default:
      break;
  }
}
body {
  margin: 0;
  box-sizing: border-box;
  height: 100vh;
  width: 100vw;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
  overflow: hidden;
}

.perspective-container {
  perspective: 500vmin;
  width: 96vmin;
  height: 96vmin;
}

.z-translation-container {
  position: relative;
  transform: translateZ(-48vmin);
  width: 100%;
  height: 100%;
  transform-style: preserve-3d;
}

.cube {
  width: 100%;
  height: 100%;
  position: relative;
  transform-style: preserve-3d;
  transition: transform 2s;
}

.cube-face {
  box-sizing: border-box;
  position: absolute;
  width: 96vmin;
  height: 96vmin;
  border: 0.5vmin solid black;
  opacity: 0.55;
}

.cube-face-front {
  transform: rotateY(0deg) translateZ(48vmin);
  background-color: blue;
  visibility: hidden;
}

.cube-face-back {
  transform: rotateY(180deg) translateZ(48vmin);
  background-color: orange;
  visibility: hidden;
}

.cube-face-left {
  transform: rotateY(-90deg) translateZ(48vmin);
  background-color: yellow;
  visibility: hidden;
}

.cube-face-right {
  transform: rotateY(90deg) translateZ(48vmin);
  background-color: purple;
  visibility: hidden;
}

.cube-face-top {
  transform: rotateX(90deg) translateZ(48vmin);
  background-color: red;
}

.cube-face-bottom {
  transform: rotateX(-90deg) translateZ(48vmin);
  background-color: green;
}
<html>
  <body class='user' onkeydown='keyboardTurn(event)'>
    <div class='perspective-container'>
      <div class='z-translation-container'>
        <div class='cube'>
          <div class='cube-face cube-face-front'></div>
          <div class='cube-face cube-face-back'></div>
          <div class='cube-face cube-face-left'></div>
          <div class='cube-face cube-face-right'></div>
          <div class='cube-face cube-face-top'></div>
          <div class='cube-face cube-face-bottom'></div>
        </div>
      </div>
    </div>
  </body>
</html>

So it appears that maybe the problem is that the faces are interfering with each other in some way, but I can’t imagine how.

Another “fix” for the problem is to shrink the cube’s container and the size of each face by half (from 96vmin to 48vmin) and that seems to clear it up as well – the problem is that it’s important to me that the cube be 96vmin on each side. Here’s an example in action:

https://codepen.io/shaundgrey/pen/ByNOKYb

//the cube and its six faces for easy refernce
var cube = document.querySelector(".cube");
var frontFace = document.querySelector(".cube-face-front");
var backFace = document.querySelector(".cube-face-back");
var leftFace = document.querySelector(".cube-face-left");
var rightFace = document.querySelector(".cube-face-right");
var topFace = document.querySelector(".cube-face-top");
var bottomFace = document.querySelector(".cube-face-bottom");

//this is the rotation matrix in which we can save the current state of the cube
var resetMatrix = new DOMMatrix();
var matrix = new DOMMatrix();

//takes a vector (rotation axis) and angle (rotation direction) as input and rotates the cube accordingly
function applyRotation(x, y, z, angle) {
  var newMatrix = new DOMMatrix().rotateAxisAngle(x, y, z, angle).multiply(matrix);
  cube.style.transform = newMatrix;
  matrix = newMatrix;
}

//takes a keyboard arrow input and creates a vector (rotation axis) and angle (rotation direction) in response, then feeds that vector and angle to applyRotation
function keyboardTurn(event) {
  switch (event.key) {
    case "ArrowRight":
      applyRotation(0, 1, 0, 45);
      break;
    case "ArrowLeft":
      applyRotation(0, 1, 0, -45);
      break;
    case "ArrowUp":
      applyRotation(1, 0, 0, 45);
      break;
    case "ArrowDown":
      applyRotation(1, 0, 0, -45);
      break;
    case "r":
      cube.style.transform = resetMatrix;
      matrix = resetMatrix;
      break;
    default:
      break;
  }
}
body {
  margin: 0;
  box-sizing: border-box;
  height: 100vh;
  width: 100vw;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
  overflow: hidden;
}

.perspective-container {
  perspective: 500vmin;
  width: 48vmin;
  height: 48vmin;
}

.z-translation-container {
  position: relative;
  transform: translateZ(-48vmin);
  width: 100%;
  height: 100%;
  transform-style: preserve-3d;
}

.cube {
  width: 100%;
  height: 100%;
  position: relative;
  transform-style: preserve-3d;
  transition: transform 2s;
}

.cube-face {
  box-sizing: border-box;
  position: absolute;
  width: 48vmin;
  height: 48vmin;
  border: 0.5vmin solid black;
  opacity: 0.55;
}

.cube-face-front {
  transform: rotateY(0deg) translateZ(24vmin);
  background-color: blue;
}

.cube-face-back {
  transform: rotateY(180deg) translateZ(24vmin);
  background-color: orange;
}

.cube-face-left {
  transform: rotateY(-90deg) translateZ(24vmin);
  background-color: yellow;
}

.cube-face-right {
  transform: rotateY(90deg) translateZ(24vmin);
  background-color: purple;
}

.cube-face-top {
  transform: rotateX(90deg) translateZ(24vmin);
  background-color: red;
}

.cube-face-bottom {
  transform: rotateX(-90deg) translateZ(24vmin);
  background-color: green;
}
<html>
  <body class='user' onkeydown='keyboardTurn(event)'>
    <div class='perspective-container'>
      <div class='z-translation-container'>
        <div class='cube'>
          <div class='cube-face cube-face-front'></div>
          <div class='cube-face cube-face-back'></div>
          <div class='cube-face cube-face-left'></div>
          <div class='cube-face cube-face-right'></div>
          <div class='cube-face cube-face-top'></div>
          <div class='cube-face cube-face-bottom'></div>
        </div>
      </div>
    </div>
  </body>
</html>

Does anyone have any idea what could be going on here? I’ve been beating my head against it for a few days now and feel completely stumped! Thank you!

Assistance Needed: Tasker + OpenAI Integration – %reply Always Outputting “=%reply” Instead of Parsed Value

What I’m trying to do: Build a Tasker profile that:

Sends a prompt to OpenAI via HTTP Request

Receives the JSON response

Parses the assistant’s reply into %reply

Displays %reply in a Flash and uses Say (TTS) to speak it aloud

Looking for help with:

Why %reply isn’t resolving even though JavaScriptlet is setting it.

Whether setLocal is working properly inside JavaScriptlets.

Whether global() is retrieving the correct content from Tasker variables.

Any Tasker best practices for scoping variables between JavaScriptlet and Tasker actions.

Ways to log/debug silent JS parsing failures (no errors shown).

Any quirks in Tasker that could cause %reply to be used before it’s actually set.

Device/Environment:

Android with Tasker installed

TTS Engine: default Google

Internet and API key are working — valid JSON is received in %gptresponse_http_data

If anyone with Tasker scripting or advanced JavaScriptlet experience has ideas, I’d really appreciate it. I’ve hit a wall. Thanks!

What I’ve tried:

Verified that %gptresponse_http_data contains valid JSON (confirmed via Flash/debug).

Switched between setGlobal() and setLocal() for the reply variable.

Rearranged task actions so Flash and Say come after the JavaScriptlet.

Checked that HTTP request output variables are named gptresponse and that I’m referencing gptresponse_http_data properly.

Hardcoded test values work every time — the issue only appears when referencing the actual HTTP response.

Confirmed that the %reply variable exists and is evaluated, but it never resolves to the JSON content unless it’s hardcoded.

Task Order:

  1. HTTP Request

URL: https://api.openai.com/v1/chat/completions

Headers:

 Authorization: Bearer sk-...

 Content-Type: application/json

Body:

{

 "model": "gpt-3.5-turbo",

 "messages": [

   {

     "role": "system",

     "content": "You are GhostCore, a    tactical AI..."

   },
   {

     "role": "user",
    "content": "%avcomm"
   }
  ]
 }

Output variable: gptresponse

  1. JavaScriptlet:

     var raw
     global("gptresponse_http_data");
     var json = JSON.parse(raw);
     setLocal("reply")
     json.choices[0].message.content);
    
  2. Flash: %reply

  3. Say: %reply

Still, %reply is output as a literal string: =%reply

What works:

The HTTP POST request to https://api.openai.com/v1/chat/completions is successful.

I correctly get data in %gptresponse_http_data (raw JSON).

When I hardcode a JSON response in a JavaScriptlet, parsing works and %reply gets set correctly.

Example of working hardcoded test:

  var raw = '{"choices":[{"message":       {"content":"This is a test."}}]}';
  var json = JSON.parse(raw);
   setLocal("reply",    json.choices[0].message.content);

Also, this basic test works fine:

setGlobal(“reply”, “JS is working”);

But here’s the issue: When I try to use the actual response data, like this:

   var raw =    global("gptresponse_http_data");
   var json = JSON.parse(raw);
   setLocal("reply",   json.choices[0].message.content);

…the Flash and Say actions both output “=%reply” instead of the actual content.

How can I make the form fill with its corresponding information from the database when it’s displayed?

I have a local project in which I edit the fields inserted in the database through a form, and the information should appear in the form because in DevTools > Network, the status shows that the data has been returned in JSON format and I can see its content.

    <form id="frmInventariosU">
      <input type="text" id="idinventarioU" hidden="" name="idinventarioU">
      <label>Articulo</label>
      <input type="text" class="form-control" id="nombre_articuloU" name="nombre_articuloU">
      <label>Tipo Modelo</label>
      <input type="text" class="form-control" id="tipo_modeloU" name="tipo_modeloU">
      <label>Color</label>
      <input type="text" class="form-control" id="colorU" name="colorU">
      <label>Marca</label>
      <input type="text" class="form-control" id="marcaU" name="marcaU">
      <label>Medida</label>
      <input type="text" class="form-control" id="medidaU" name="medidaU">
      <label>Existencia</label>
      <input type="text" class="form-control" id="existenciaU" name="existenciaU">
      <label>Entrada</label>
      <input type="text" class="form-control" id="entradaU" name="entradaU">
      <label>Salida</label>
      <input type="text" class="form-control" id="salidaU" name="salidaU">
    </form>

    <script type="text/javascript">
        function agregaDatosInventario(idinventario){

            $.ajax({
                type:"POST",
                data:"idinventario=" + idinventario,
                url:"../procesos/inventario/obtenDatosInventario.php",
                success:function(r){
                    dato=jQuery.parseJSON(r);
                    $('#idinventarioU').val(dato['id_inventario']);
                    $('#nombre_articuloU').val(dato['nombre_articulo']);
                    $('#tipo_modeloU').val(dato['tipo_modelo']);
                    $('#colorU').val(dato['color']);
                    $('#marcaU').val(dato['marca']);
                    $('#medidaU').val(dato['medida']);
                    $('#existenciaU').val(dato['existencia']);
                    $('#entradaU').val(dato['entrada']);
                    $('#salidaU').val(dato['salida']);
                }
            });
        }
</script>

This code returns the JSON I see in DevTools > Network with the data that should be inside the form

<?php

    require_once "../../clases/Conexion.php";
    require_once "../../clases/Inventario.php";

    $obj = new inventario();
    
    echo json_encode($obj->obtenDatosInventario($_POST['idinventario']));

?>

The function returns an array with the information

    public function obtenDatosInventario($idinventario){
      $c= new conectar();
      $conexion=$c->conexion();
    
      $sql="SELECT id_inventario, 
              nombre_articulo,
              tipo_modelo,
              color,
              marca,
              medida,
              existencia,
              entrada,
              salida
        from inventario";
      $result=mysqli_query($conexion,$sql);
      $ver=mysqli_fetch_row($result);
    
      $datos=array(
          'id_inventario' => $ver[0],
          'nombre_articulo' => $ver[1],
          'tipo_modelo' => $ver[2],
          'color' => $ver[3],
          'marca' => $ver[4],
          'medida' => $ver[5],
          'existencia' => $ver[6],
          'entrada' => $ver[7],
          'salida' => $ver[8]
            );
      return $datos;
    }

I suspect it’s an issue with the IDs, but I still can’t figure out how to fix it.
Any idea what the problem might be? Thanks in advance.

Can I use :hover on an element that is invisible but still takes up space?

I’m experimenting with CSS and came across an edge case I’m curious about.

Suppose I have a div> that is styled to be completely invisible, either via opacity: 0 or visibility: hidden, but it’s still present in the DOM and occupies layout space (or is absolutely positioned). I want to know if it’s possible to trigger a :hover effect on such an element.

Here’s a simple example:

.hover-target { width: 100px; height: 100px; background-color:
red; opacity: 0; /* Or visibility: hidden; */ position: absolute;
}
.hover-target:hover { background-color: green; opacity: 1; }

What I want to know:
Will :hover work on an element that’s invisible via opacity: 0 or visibility: hidden?

Is there a difference between opacity: 0 and visibility: hidden in terms of how they interact with pointer events like :hover?

If it doesn’t work, is there any CSS-only workaround to make an element invisible (visually) but still respond to hover events?

I know display: none completely removes the element from the rendering tree, so it’s not hoverable. But what about these subtler cases?

Thanks in advance for your insights!