Updating bitnami stack, WordPress, deprecated errors [duplicate]

Thanks in advance, at one time I was on top of all things PHP related. I’m attempting to update a website on the bitnami stack. The theme is out of support and I’m tasked with fixing everything.

I’m getting many deprecated errors as show below. Can someone point me in the right direction? Google isn’t much help.

   function init() {
        $this->dir = dirname( __FILE__ );


[06-Jul-2025 17:48:42 UTC] PHP Deprecated:  Creation of dynamic property Carell_Custom_Fields::$dir is deprecated in /bitnami/wordpress/wp-content/plugins/carell-custom-fields/ccf.php on line 39
[06-Jul-2025 17:48:42 UTC] PHP Deprecated:  Creation of dynamic property Carell_Custom_Fields::$url is deprecated in /bitnami/wordpress/wp-content/plugins/carell-custom-fields/ccf.php on line 40
[06-Jul-2025 17:48:42 UTC] PHP Deprecated:  Creation of dynamic property Carell_Custom_Fields::$api is deprecated in /bitnami/wordpress/wp-content/plugins/carell-custom-fields/ccf.php on line 60
[06-Jul-2025 17:48:42 UTC] PHP Deprecated:  Creation of dynamic property Carell_Custom_Fields::$form is deprecated in /bitnami/wordpress/wp-content/plugins/carell-custom-fields/ccf.php on line 61
[06-Jul-2025 17:48:42 UTC] PHP Deprecated:  Creation of dynamic property Carell_Custom_Fields::$field_group is deprecated in /bitnami/wordpress/wp-content/plugins/carell-custom-fields/ccf.php on line 62
[06-Jul-2025 17:48:42 UTC] PHP Deprecated:  Creation of dynamic property Carell_Custom_Fields::$fields is deprecated in /bitnami/wordpress/wp-content/plugins/carell-custom-fields/ccf.php on line 63

JS In the loop, if the predefined function throws an exception, the loop stops iterating

I’m using a for loop and within this loop I utilize a predefined function from our library that employs try/catch and throw.

I need to iterate through an array and if an array value causes an error I want to move to the next iteration. However, I’ve encountered an issue where the loop breaks when an error is thrown.

for (let i = 0; i < strSplited.length; i++) {
  let omadaObject = new OmadaGeneric(app_name, SRRecID); //Initialize the object;
  console.log('Omada Object created for the iteration ' + i);
  let loginId = strSplited[i];
  console.log("the Login Id is " + loginId)
  console.log("the iteration  number************************************** n" + i)
  
  try {
    omadaObject.getOmadaUserIDFromLoginId(loginId);
    omadaObject.doOmadaRoleIDAssignment(omadaRoleId_shopfloor, loginId);
    console.log("the Role was successfully assigned to the user ");
  } catch (e) {
    console.log(e.message)
  }
}

How to store the data on the button

How to access the data of buttons in JS for example

const button = document.getElementById("button");
button.addEvenListner('click', num => num=1);

I want to access the data and store it. How can I do that?
When I try to console.log(button) it ends up giving undefined

How to solve in React Native [Error: Unsupported FormDataPart implementation] post FormData?

I’m using React Native with Expo and I’m trying to upload a images using formData with post and ‘expo-image-picker’. WHen I try to upload a image I get [Error: Unsupported FormDataPart implementation], I don’t understand the iussue, is anyone could help me ?

here’s the code:

const requestPermissions = async () => {
    const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync();
    if (status !== 'granted') {
      Alert.alert('Permissions Required', 'We need permission to access your photo library.', [
        { text: 'OK' },
      ]);
      return false;
    }
    return true;
  };

  const onUploadImage = async asset => {
    console.log('file', asset);
    
    const fileToUpload = {
      uri: asset.uri,
      name: asset.fileName ?? `image_${Date.now()}.jpg`,
      type: asset.mimeType ?? 'image/jpeg',
    };

    const formData = new FormData();
    formData.append('file', fileToUpload);  

    try {
      setIsLoading(true);

      const response = await postAuthenticatedAPI({
        token: user?.access_token,
        isChatEndpoint: false,
        formData: true,
        endpoint: UPLOAD_FILE,
        payload: formData,
      });

      console.log('res', response);

      if (response) {
        setImageData(prev => ({
          ...prev,
          id: `img_${Date.now()}`,
          url: asset.uri,
        }));

        onImageChange('cover_image', response?.file || asset.uri);
      }
    } catch (error) {
      setModalConfig({
        title: 'Error',
        subtitle: error?.message || 'Error fetch',
        type: 'error',
      });
      setShowModal(true);
    } finally {
      setIsLoading(false);
    }
  };

  const showImageOptions = () => {
    if (isLoading) return;

    Alert.alert('Select Image', 'Choose where you want to select the image from', [
      {
        text: 'Gallery',
        onPress: pickImageFromGallery,
      },
      {
        text: 'Camera',
        onPress: takePhoto,
      },
      {
        text: 'Cancel',
        style: 'cancel',
      },
    ]);
  };

  const pickImageFromGallery = async () => {
    const hasPermission = await requestPermissions();
    if (!hasPermission) return;

    try {
      const image = await ImagePicker.launchImageLibraryAsync({
        mediaTypes: 'images',
        allowsEditing: true,
        aspect: [1, 1],
        quality: 0.8,
      });

      if (!image.canceled && image.assets && image.assets.length > 0) {
        const asset = image.assets[0];

        await onUploadImage(asset);
      }
    } catch (error) {
      Alert.alert('Errore', error);
    }
  };

  const takePhoto = async () => {
    const { status } = await ImagePicker.requestCameraPermissionsAsync();
    if (status !== 'granted') {
      Alert.alert('Permissions Required', 'We need permission to access your camera.', [
        { text: 'OK' },
      ]);
      return;
    }

    try {
      const image = await ImagePicker.launchCameraAsync({
        allowsEditing: true,
        aspect: [1, 1],
        quality: 0.8,
      });

      if (!image.canceled && image.assets && image.assets.length > 0) {
        const asset = image.assets[0];

        await onUploadImage(asset);
      }
    } catch (error) {
      Alert.alert('Errore', error);
    }
  };

here’s my post function:

export const postAuthenticatedAPI = async ({
  payload,
  endpoint,
  token,
  formData = false,
  isChatEndpoint = false,
}) => {
  const baseUrl = isChatEndpoint
    ? process.env.EXPO_PUBLIC_BASE_CHAT
    : process.env.EXPO_PUBLIC_BASE_URL;
  const url = baseUrl + endpoint;
  
  try {
    const headersWithFormData = {
      Authorization: `Bearer ${token}`,
    };

    const withoutFormDataHeader = {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${token}`,
    };

    const response = await fetch(url, {
      method: 'POST',
      headers: formData ? headersWithFormData : withoutFormDataHeader,
      body: formData ? payload : JSON.stringify(payload),
    });

    if (response.status === 200 || response.status === 201) {
      return await response.json();
    } else throw new Error('Server error');
  } catch (e) {
    const error = new Error(e?.message || 'Something went wrong');
    error.info = e.info || null;
    error.status = e.status || null;
    throw error;
  }
};

Where am I wrong ?

Hope. fund_loan app customer. CARE. helpline. NUMBER//-9973919301//-7827186zhh ·ransi

I’m trying to get a bunch of MP3 blob files off of a website that stored them to the browser cache in IndexedDB > localforage. In the developer console, I tried a simple:

const request = window.indexedDB.open(“localforage”, 1);

console.log(request)

But the readyState is stuck in “pending”. Obviously the site has something going on in the background. Is there a way to kill whatever request is currently at the head of the queue or open a second “read only” connection?

From initial research, this seemed to be the only way to get the blob files to download in bulk. I can do them one by one by hitting play on the offline player and stripping it from the HTML, but it takes forever since I have to play each one before the blob loads and I can download it. The blob file is a straight MP3 – once it’s downloaded, I just add the .mp3 extension and it works. If there is a better way to get these files than trying to force my way into IndexedDB, I’m open to suggestions bb

I’m trying to get a bunch of MP3 blob files off of a website that stored them to the browser cache in IndexedDB > localforage. In the developer console, I tried a simple:

const request = window.indexedDB.open(“localforage”, 1);

console.log(request)

But the readyState is stuck in “pendi vvng”. Obviously the site has something going on in the background. Is there a way to kill whatever request is currently at the head of the queue or open a second “read only” connection?

From initial research, this seemed to be the only way to get the blob files to download in bulk. I can do them one by one by hitting play on the offline player and stripping it from the HTML, but it takes forever since I have to play each one before the blob loads and I can download it. The blob file is a straight MP3 – once it’s downloaded, I just add the .mp3 extension and it works. If there is a better way to get these files than trying to force my way into IndexedDB, I’m open to suggestio bbns

Is there a way to add a next step asking me the type of payment (e.g. Credit Card, Cash) for IOS Shortcuts

Hi i am trying to create a IOS shortcut and record expense directly to Notion using this tutorial i found, but i am struggling to add 1 more new category (Type of Payment). Currently it allows me to record:

  1. Expense Name
  2. Type of Expense (e.g. Shopping, Food etc)
  3. Amount
  4. Type of Payment (e.g. Credit Card, Cash etc) – Missing step

I have little to no coding knowledge, please help!

Tutorial: https://www.youtube.com/watch?v=6FAhX0vk3Yc
Setting up: https://www.anotioneer.com/blog/setting-up-the-record-expenses-apple-shortcut

How to build a spreadsheet-like editable table in React (e.g. with react-table or custom logic)?

I’m working on a React assignment where I need to create a table UI that works like a spreadsheet — with features like:

Editable cells

Dynamic number of rows/columns

(Optional: drag and drop columns, copy/paste support, etc.)

I’ve tried using react-table and some custom input elements, but I’m struggling to make cells editable or dynamically render rows and columns properly.
I’m building a spreadsheet-like editable table using React with TypeScript and Tailwind CSS. I want features like editable cells, dynamic rows/columns, and possibly keyboard navigation.

I’d appreciate guidance on:

How to make cells editable properly?

Whether react-table is good for this use case?

Is there a way to open a second connection to IndexedDB or kill a prior request so the next loads?

I’m trying to get a bunch of MP3 blob files off of a website that stored them to the browser cache in IndexedDB > localforage. In the developer console, I tried a simple:

const request = window.indexedDB.open("localforage", 1);
console.log(request)

But the readyState is stuck in “pending”. Obviously the site has something going on in the background. Is there a way to kill whatever request is currently at the head of the queue or open a second “read only” connection?

From initial research, this seemed to be the only way to get the blob files to download in bulk. I can do them one by one by hitting play on the offline player and stripping it from the HTML, but it takes forever since I have to play each one before the blob loads and I can download it. The blob file is a straight MP3 – once it’s downloaded, I just add the .mp3 extension and it works. If there is a better way to get these files than trying to force my way into IndexedDB, I’m open to suggestions.

Boolean based authentication in java script

This is my first website so any advice will be appreciated.

Main questions

How can I stop functions from executing in java script?
Is this a bad authentication method? IE would I be better of building something else?

I am making a website that my friends and I can upload all the pictures we took on a trip we went on. I do not want random people to be able to upload to the website. So I am requiring a key before the upload and submit buttons are shown. I am using wix and adding my own java-script.

I have a back end server that will check the value of a key and return a boolean. That triggers the front end to change. I know this isn’t secure so I would like deny submissions if the returned boolean is false to the upload button.

I have tried an if statement that should break out of function by calling return. That did not work. I have also tried using a try catch block where an error is thrown if the boolean is false

What else can I try block the submit?

The code is below

$w('#button1').onClick((event) => {
   if (!allowedUpload) {
       console.log(curKey,"not authorized");
       return;
    }
   console.log(curKey," may upload");
  
});



/* try catch attempt

try {
   if (allowedUpload === false) {
     throw new Error("notAuthorized");
       console.log(curKey,"not authorized");

    }
   console.log(curKey," may upload");
} catch (error) {
       console.log("may not upload");
} 

*/

Display Hidden Table Cell on click of another Table Cell in HTML, CSS, and JavaScript

So here’s my problem…

I’m trying to create a fun little “avoid the mines” game using HTML, CSS, and JavaScript.

The objective is to get to the end of the level by clicking on a grid of tiles while avoiding clicking on a mine tile (this will give you a game over).
To do this, you have to click on each tile sequential order, which will reveal the next adjacent tile. For example: clicking on tile A2 will reveal tile A3, clicking on tile A3 will reveal tile A4, and so on.

Figure 1 showing all the currently visible tiles in the grid (which is just a table with some CSS styling applied).

Figure 2 showing a tile that has been clicked on (A2), along with the adjacent tile (A3) that should be revealed by clicking on A2.

However, I can’t figure out how to make the “reveal tile by clicking on an adjacent tile” function work.

If anyone could help me figure out how to make the hidden tiles be revealed sequentially by clicking on another already-visible adjacent tile, I would be very grateful.

(Ideally, I’d like to avoid having to use JavaScript as much as possible. But if it has to be done, then please share your JavaScript-based solutions.)

Also, Here’s the HTML and CSS code I have for the table…

body {
    background-color: black;
}

table {
    border-collapse: collapse;
    position: absolute;
}

td {
    width: 64px;
    height: 64px;
    text-align: center;
    justify-content: center;
}

.TileStart {
    border: 1px solid lightgray;
    background-color: white;
}

.Tile {
    border: 1px solid lightgray;
    background-color: black;
    cursor: pointer;
}

.TileFinish {
    border: 1px solid lightgray;
    background-color: black;
    cursor: pointer;
}

#A4, #A5 {
    visibility: hidden;
}
<!DOCTYPE html>
<html>
<head>
  <title>Minefield Game Hidden Tiles Test</title>
  <link rel="stylesheet" href="hidden-tiles-test-styles.css">
  <meta charset="utf-8">
  <meta name="description" content="Testing hidden cells in tables.">
 </head>
 <body>
  <table>
    <tr>
        <td class="TileStart" id="A1"></td>
        <td class="Tile" id="A2" onclick="style='background-color: darkgray;'"></td>
        <td class="Tile" id="A3" onclick="style='background-color: darkgray;'"></td>
        <td class="Tile" id="A4" onclick="style='background-color: darkgray;'"></td>
        <td class="TileFinish" id="A5" onclick="style='background-color: white;'"></td>
    </tr>
  </table>
 </body>
 </html>

Phase 2 of Google Apps Script Web App Fails to Load via ?page= Query — No Logs Triggered

Introduction:
I’m building a multi-phase contractor dashboard in Google Apps Script using a custom HTML frontend and doGet(e) routing. The form UI loads in three sequential phases (?page=1, ?page=2, ?page=3), and each phase is served by the same doGet(e) function using an if/else switch on e.parameter.page.

The issue:
?page=1 loads perfectly. However, when navigating to ?page=2, the app freezes with a blank page, and no error appears in the Execution Log. No doGet(e) execution is triggered, which leads me to suspect:

Either a client-side blocking bug in the Phase 1 HTML,

Or that a server-side error is failing silently in Apps Script.

Despite console debugging and test logging, no entry shows in the Executions log for the second page load.

What we’ve tried:
Verified that the navigation links are valid.

Used Logger.log() and console.log() to trace phase entry points.

Checked HTML and JS for missing form elements or syntax errors.

Deployed a test version with minimal HTML to isolate where the error might occur.

Question:

How can I debug Apps Script doGet routing when nothing appears in the Execution Log?

Also, are there known conditions (like malformed HTML or JS errors) that can prevent doGet() from firing at all?

Invertase Stripe Payment Extension Issue: Metered Pricing

I am trying to get the invertase extension to work with metered pricing but I keep getting the error: {message: ‘Quantity should not be specified where usage_type is metered. Remove quantity from line_items[0]‘} even though I have no quantity part of the adddoc package.

I am not setting the quantity anywhere in my code but I can’t get it to work. I have tried setting quantity to null, unset etc but it just gives invalid integer then.

Not sure what else to provide but happy to give any information needed.

'use client';

import { auth, db } from '@/firebaseConfig';
import type { FirebaseApp } from 'firebase/app';
// make sure db is exported here
import { addDoc, collection, onSnapshot } from 'firebase/firestore';
import { getFunctions, httpsCallable } from 'firebase/functions';

import { logger } from '@/lib/default-logger';

const PRICE_ID = process.env.NEXT_PUBLIC_STRIPE_METERED_PRICE!;
const CLOUD_RUN_ROOT = process.env.NEXT_PUBLIC_CLOUD_RUN_ROOT!;

/**
 * Creates a Checkout Session document in
 *   stripe_customers/{uid}/checkout_sessions
 * and waits for the extension to fill in `url`.
 */
export async function getCheckoutUrl(): Promise<string> {
  const user = auth.currentUser;
  if (!user) throw new Error('Must be signed-in first');

  // 1️⃣  Create the Checkout-Session request doc
  const sessionRef = await addDoc(collection(db, 'stripe_customers', user.uid, 'checkout_sessions'), {
    price: PRICE_ID, // single-price subscription
    mode: 'subscription',
    success_url: window.location.href,
    cancel_url: window.location.href,
    metadata: { storeId: user.uid },
  });

  // 2️⃣  Listen for the extension to populate `url` or `error`
  return new Promise<string>((resolve, reject) => {
    const unsubscribe = onSnapshot(
      sessionRef,
      (snap) => {
        const data = snap.data();
        if (!data) return;

        if (data.error) {
          unsubscribe();
          logger.error('Stripe ext error', data.error);
          reject(new Error(data.error.message ?? 'Stripe extension failed'));
        }

        if (data.url) {
          unsubscribe();
          resolve(data.url as string);
        }
      },
      (err) => {
        unsubscribe();
        reject(err);
      }
    );

    setTimeout(() => {
      unsubscribe();
      reject(new Error('Timed out waiting for Stripe Checkout URL'));
    }, 60_000);
  });
}

How do I redesign the JSONeditor to display JSON data so that the design of the fields and values ​is more user-friendly [closed]

How do I redesign the JSONeditor to display JSON data so that the design of the fields and values ​​is more user-friendly? The current design is completely unsuitable for this purpose. I would like the design to be dynamic, so that the fields and values ​​are generated from the JSON data.

    <div id="json-editor-container" style="height: 500px; border: 1px solid #ccc;"></div>

function onEditingStart(e) {
    currentEditingData = e.data;

    setTimeout(() => {
        const container = document.getElementById("json-editor-container");
        if (container) {
            container.innerHTML = "";

            //const options = {
            //    mode: 'form',
            //    // modes: ['tree', 'form', 'code'],
            //    // disableEditJson: true,     //  JSON
            //    // disableProperties: true ,   //
            //    onChangeJSON: function (json) {
            //        if (e.component && e.data && jsonEditorInstance) {
            //            console.log(jsonEditorInstance);
            //            const updatedJson = jsonEditorInstance.get();
            //            console.log(updatedJson);
            //            // e.component.cellValue(e.key, "Parameters", JSON.stringify(updatedJson));
            //            currentEditingData.Details = JSON.stringify(updatedJson);
            //        }
            //    }
            //};
            const options = {
                modes: ['tree', 'form', 'view'],
                search: true,
                onError: (err) => console.error(err),

                // القالب الديناميكي الرئيسي
                templates: [
                    {
                        text: 'Dynamic Image Preview',
                        field: '*', // تطبق على جميع الحقول
                        template: (value, path) => {
                            // الفحص الديناميكي إذا كانت القيمة تمثل صورة
                            console.log(value);
                            console.log(path);
                            if (isImageField(value)) {
                                return renderImagePreview(value);
                            }
                            // فحص خاص للحقول التي تحتوي على مصفوفة من الصور
                            if (Array.isArray(value) && value.every(isImageField)) {
                                return value.map(img => renderImagePreview(img)).join('');
                            }

                            // إرجاع القيمة الأصلية إذا لم تكن صورة
                            return value;
                        }
                    }
                ]
            };
            jsonEditorInstance = new JSONEditor(container, options);

            try {
                const processedData = e.data.Details ? JSON.parse(e.data.Details) : {};
                console.log(processedData);
                const initialJson = processDynamicFields(processedData, baseUrl+'/');
                //const initialJson = processedData ? JSON.parse(processedData) : {};
              //  const editor = new JSONEditor(container, options, processedData);
                console.log(initialJson);
                jsonEditorInstance.set(initialJson);
            } catch (err) {
                jsonEditorInstance.set({});
            }
        }
    }, 100);
}

Recording audio using expo-audio not releasing instance

I have a chat/messaging app with audio recording feature where users can send voice messages.

I am currently using the old, deprecated expo-av library and trying to migrate the newer version expo-audio.

In the old version (expo-av), after the user finishes recording audio and I complete uploading (processing) it, I would call a method:

await recording.stopAndUnloadAsync();

Which releases the instance, so user can record a new audio

In the newer version (expo-audio), I can’t find a similar method to call. In the documentation, it says just do:

audioRecorder.stop();

But it seems that this method doesn’t clear the current memory/release the instance.

If a user records audio once, then tries again to record new audio, they get the previous recorded audio (same audio and same local uri)

My code:

import { RecordingPresets, useAudioRecorder } from 'expo-audio';
import { useState } from "react";


export default function useRecorder() {
    const audioRecorder = useAudioRecorder(RecordingPresets.HIGH_QUALITY);
    const [isRecording, setIsRecording] = useState(false);

    const startRecording = async () => {
        await audioRecorder.prepareToRecordAsync();
        audioRecorder.record();
        setIsRecording(true);
    };

    const stopRecording = async () => {
        await audioRecorder.stop();
        console.log(audioRecorder.uri)
        setIsRecording(false);
    };

    return { startRecording, stopRecording };
}

I am using the recorder as a hook with two methods (I have omitted the permission part for simplicity).
The first method starts the recording and the second method stops the recording.

In the stopRecording method, I console.log the uri for the file. Every time I am getting the very same uri and if I play it, I get the same audio I recorded the first time.

React Router renders wrong component for the grandchildren. @react-router/dev

Routes.ts

import { 
  type RouteConfig,
  index,
  route,
  layout
} from "@react-router/dev/routes";

export default [
  layout("layouts/main_layout.tsx", [
    route("dashboard", "routes/dashboard/index.tsx", [
      route("employee", "routes/dashboard/employee/index.tsx", [
        route("add", "routes/dashboard/employee/add/index.tsx")
      ]),
    ]),
    route("*", "routes/not-found.tsx")
  ]),
  layout("layouts/auth_layout.tsx", [
    route("/login", "routes/login.tsx"),
  ])
] satisfies RouteConfig;

./routes/dashboard/employee/add/index.tsx

import EmployeeAddPage from "~/pages/dashboard/employees/Add";

export function meta() {
  return [
    { title: "Dashboard - Employee - Add - Index" },
    { name: "dashboard", content: "Index" },
  ];
}

export default function Index() {
  return <EmployeeAddPage />;
}
export default function EmployeeAddPage() {
  return (
    <div>
      <input name={"trajce"} value={"trajce"} />
      asdasd

      <p>asdasd</p>
    </div>
  )
}

./routes/dashboard/employee/index.tsx

import EmployeeListPage from "~/pages/dashboard/employees/List";

export function meta() {
  return [
    { title: "Dashboard - Employee" },
    { name: "dashboard", content: "Index" },
  ];
}

export default function Index() {
  return <EmployeeListPage />;
}

browser image

For some reason the <EmployeeListPage /> component is showing on "/dashboard/employee/add", instead of <EmployeeAddPage />. Is there some limitation to the routing depth, like only the parent and children working, but children’s children and so on, not? Is this a bug or I need to configure this or maybe the code is broken?

I see “Dashboard – Employee – Add – Index” on the tab