How to create a function to determine the current school grade based on graduation year and month [closed]

I’m trying to create a function in TypeScript like the one below:

getSchoolGradeLabel(gradYear: number, gradMonth: number): string

This function takes the graduation year (gradYear) and graduation month (gradMonth) as arguments and returns a string indicating the current school grade, such as:

  • Junior High School Year 1
  • Junior High School Year 2
  • Junior High School Year 3
  • Senior High School Year 1
  • Senior High School Year 2
  • Senior High School Year 3
  • If the student has already graduated → “Graduated in XXXX”

The timing of the school year change depends on the graduation month:

Graduation Month Grade Transition Timing
March April 1st of the following year
June July 1st of the same year
September October 1st of the same year
December January 1st of the following year

For example, as today is April 25, 2025, the result of calling:

getSchoolGradeLabel(2029, 3)

should be: “Junior High School Year 2”.

How can I enforce code integrity for a locally installed (unpacked) Chrome extension so it refuses to run if tampered with?

Background

I’m developing a Chrome extension distributed locally in “unpacked” mode, outside of the Chrome Web Store. I need a way to guarantee that if any part of the extension’s code (JS, HTML, CSS, manifest, etc.) is modified, the extension immediately stops working—similar to the signature-based protection that Chrome Store extensions enjoy.

What I’ve Tried

  • There is an existing discussion from 12 years ago on Stack Overflow:
    How to check the authenticity of a Chrome extension?
    The primary recommendation was to obfuscate the code. Obfuscation only slows down reverse-engineering; it does not prevent actual code modification.

  • Obfuscation adds friction but does not enforce integrity.

Question

In 2025, is there any reliable technique or standard that allows embedding a cryptographic signature or verified hash within an unpacked extension so that, at startup or runtime, the extension can:

  • Detect if any internal file has been altered (beyond a simple hard-coded checksum).

  • Halt its own execution if the integrity check fails.

Examples of approaches I’m curious about:

  • A form of code signing that can be performed locally and verified by the extension’s own scripts.

  • Remote attestation: fetching an externally signed manifest and validating it offline.

  • Leveraging Service Workers, WebAssembly, or Native Messaging for more secure tamper-detection.

  • Any open-source libraries or commercial solutions specifically designed for tamper detection in unpacked Chrome extensions.

Additional Details

  • Using Manifest V3.

  • Must work when installed manually via .zip or by loading a folder in chrome://extensions.

  • Upon detecting tampering, the extension should disable itself or display an “Invalid code” warning.

What modern approaches or technologies do you recommend to achieve robust code integrity and tamper-detection for an unpacked Chrome extension?

Why Is pLimit() Not A Function?

I have a class that controls a list of ips. Every single item in that list is an instance of another class, that controls data around a specific ip. One of the methods of each ip, is the ability to search itself on a website.

With Promise.All, I reach the common parallel request flooding issue; decided to use p-limit to solve this. However, instead of creating a concurrency limit on my parallels calls of Promise, pLimit() simply causes an error, because it isn’t being recognized as a function.

import NeoIp from './NeoIp.js';
import { v4 as uuidv4 } from 'uuid';
import pLimit from 'p-limit'; //Attempted this, and the two at the bottom.
//import * as pLimitModule from 'p-limit';
//const pLimit = pLimitModule.default || pLimitModule;

class NeoIpList {
// [...] Abbreviated

    async arinSearchAll() {
        // Arin has a daily api limit of 100,000
        // Maximum of 10 calls per second.
        const alreadySearched = new Set(); // More appropriate than Map here

        // --------------------------
        //#region pLimit, Concurrency
        // --------------------------

        try {
            const alreadySearched = new Set(); // More appropriate than Map here
            const limit = pLimit(5); // Limit to 5 concurrent requests

            const tasks = this.list
                .map((singleIp) => {
                    if (!alreadySearched.has(singleIp)) {
                        alreadySearched.add(singleIp);
                        return limit(() => singleIp.arinSearchSingle());
                    }
                    return null;
                })
                .filter(Boolean); // Remove nulls from already-searched IPs

            const results = await Promise.all(tasks);
            return results;
// [...] No longer relevant.
TypeError: pLimit is not a function

Aside from checking the different, commented-out approaches above, I’ve also gone ahead and verified that p-limit is, in fact, downloaded with npm show p-limit, and the result is as follows:

npm show p-limit

[email protected] | MIT | deps: 1 | versions: 19
Run multiple promise-returning & async functions with limited concurrency
https://github.com/sindresorhus/p-limit#readme

keywords: promise, limit, limited, concurrency, throttle, throat, rate, batch, ratelimit, task, queue, async, await, promises, bluebird

dist
.tarball: https://registry.npmjs.org/p-limit/-/p-limit-6.2.0.tgz
.shasum: c254d22ba6aeef441a3564c5e6c2f2da59268a0f
.integrity: sha512-kuUqqHNUqoIWp/c467RI4X6mmyuojY5jGutNU0wVTmEOOfcuwLqyMVoAi9MKi2Ak+5i9+nhmrK4ufZE8069kHA==
.unpackedSize: 10.3 kB

dependencies:
yocto-queue: ^1.1.1

maintainers:
- sindresorhus <[email protected]>

dist-tags:
latest: 6.2.0

published 4 months ago by sindresorhus <[email protected]>

Could use a few more ideas on troubleshooting this.

Alignment for seachbar in the header

enter image description here

Above you can see my issue. Im having trubble making it so that the search bar stays within the header. What do I do? enter code here

enter code here 
/* Header Search Styles */
.search-container-header {
    background-color: var(--light-green) !important;
    max-width: 30vw; 
    margin-top: 1rem;
    border: 2px solid rgba(255, 255, 255, 0);
    border-radius: 28px;
    height: 6vh;
    padding: 0.5rem; 
    box-sizing: border-box;
     margin: 0; 
  }
.search-wrapper-header{
  display: flex; /*not doing anything :(((*/
}

.input-search-header {
  font-size: 1rem;
  width: calc(100% - 2.8rem);
  background-color: var(--light-green) !important;
  border: 2px solid transparent;  
  border-radius: 5px;
  outline: none; 
  height: 2rem; 
  color: var(--dark-green);
  }
 /* When the search bar is visible */
.search-wrapper-header.active .search-container-header {
display: block; /* Make it visible when active */
}
   /* code from other doc */
   header {
     background-color: var(--red);
     height: 5rem;
     position: relative; /* Allow absolute positioning of inner elements */
     z-index: 10;
    }

    nav a {
    color: var(--off-white);
    text-decoration: none;
    }

    .nav-space {
      display: flex;
      justify-content: space-between;
      }

     nav ul {
      display: flex;
      list-style: none;
      justify-content: flex-end;
      }

       /*html added for searsh bar in js:*/

       enter code here 
       <div class="search-container-header">
         <input class="input-search-header" type="search" id="search-header" data-    search="header">
       </div>
       <div class="search-show-header" data-show-container></div>
       <template data-content-template>
         <div class="title-content-header">
            <p class="search-result-header" data-title></p>
         </div>
       </template>

Interception xhr requests after pressing the load more button with puppeteer

Initially two json files arrive on the site – the rest arrive after clicking the ‘load more’ button. I’m trying to intercept all requests. The example shows how I am waiting for the button to appear and click it accordingly. But so far I’m capturing only two requests – although there should be three, because I’ve already pressed the button once.

How can I wait for the rest of the xhr to intercept after pressing the ‘load more’ button?

const grab = async(url) => { 
  const browser = await puppeteer.launch({ headless: false});
  const page = await browser.newPage();

  await page.setRequestInterception(true);
  page.on("request", async (request) => {
    const current = await request.url();
    if (current.includes('betty-variants')) {
     console.log(request.url())
    }
  //This clicking not working here, the page does not see this selector
  // await page.waitForSelector('.well-sm.well p.text-primary.pull-left span', { timeout: 5000})
  // await page.click('.well-sm.well p.text-primary.pull-left span')


// Allow the request to be sent
    await request.continue();
  });

  await page.goto(url, { waitUntil: 'networkidle2' });

  await page.waitForSelector('.well-sm.well p.text-primary.pull-left span');      
  await page.click('.well-sm.well p.text-primary.pull-left span')

  await browser.close(); 
};

I tried getting the data after clicking on the button, but I only get the standard two json responses from the site.

Why my input validation function and mask for it are not working?

I have a problem. There is a parent component Form/index.vue , which contains an input for a phone number, it is linked to v-model. But for some reason, validating the mask using a function in the parent component Input does not work, only in mozilla

form component input

<MainPageFormNumberInput
  :error="inputErrorsVar.numberError"
  v-model="form_data.number"
    @update:error="updateNumberError"
   />` 
connects to the field 
`const form_data = reactive({
  fio: "",
  class: "",
  number: "",
  email: "",
  direction: "",
});

MainPageFormNumberInput :

<template>
  <CustomInput
    :text="'Number'"
    :error="error"
    v-model="model"
    @input="formatPhone"
    @focus="getPrefix"
    @blur="removePrefix"
    @update:error="$emit('update:error', $event)"
  />
</template>

<script setup>
const props = defineProps({
  error: {
    type: Boolean,
  },
});
const emits = defineEmits(["update:error"]);
const model = defineModel();
const phoneNumber = ref("");
const formatPhone = (event) => {
  let numbers = event.target.value.replace(/D/g, "");

  if (numbers.length > 0 && numbers[0] !== "7") {
    numbers = "7" + numbers.substring(1);
  }
  numbers = numbers.substring(0, 11);
  phoneNumber.value = numbers.length > 0 ? "+" + numbers : "";
  let formatted = "+7";
  if (numbers.length > 1) {
    formatted += " (" + numbers.substring(1, 4);
  }
  if (numbers.length > 4) {
    formatted += ") " + numbers.substring(4, 7);
  }
  if (numbers.length > 7) {
    formatted += " " + numbers.substring(7, 9);
  }
  if (numbers.length > 9) {
    formatted += "-" + numbers.substring(9, 11);
  }
  model.value = formatted;
};

const getPrefix = (e) => {
  if (e.target.value.length === 0) {
    model.value = "+7";
  }
};
const removePrefix = (e) => {
  if (e.target.value === "+7") {
    model.value = "";
  }
};
</script>

Custom input :

<template>
  <div class="input-field" :class="{ 'has-error': showError }">
    <input
      required=""
      :placeholder="placeholder"
      autocomplete="off"
      :type="type"
      name="text"
      :id="text"
      v-model="model"
      @blur="blurHandler"
      @focus="focusHandler"
      @input="inputHandler"
    />
    <label :for="text">
      {{ text }}
    </label>
  </div>
</template>

<script setup>
const emits = defineEmits(["blur", "focus", "input", "update:error"]);
const props = defineProps({
  text: String,
  placeholder: {
    type: String,
    required: false,
  },
  type: {
    type: String,
    required: false,
    default: "text",
  },
  error: {
    type: Boolean,
    default: false,
  },
});

const model = defineModel();
const isDirty = ref(false);

const showError = computed(() => {
  return props.error && model.value.length > 0;
});
function blurHandler(event) {
  isDirty.value = true;
  emits("blur", event);
}

function focusHandler(event) {
  emits("focus", event);
}

function inputHandler(event) {
  emits("input", event);
}
watch(model, (newVal) => {
  if (newVal.length === 0 && props.error) {
    emits("update:error", false);
  }
});

I searched a lot of information on this, read the documentation, asked the gpt chat and tried to use a bunch of props and emits instead of defineModel, but it didn’t give any results

Remove trailing decimals without rounding up [duplicate]

For example, I have a number 123.429. How can I remove the trailing decimals without rounding up to two decimal places. Hence, I need the number to be up to one decimal point i.e. 123.4

-0.5 to -0.58 to -0.5(output)
-0.9 to -0.99 to -0.9(output)

-1.00 to -1.09 to -1.0(output)
-1.10 to -1.19 to -1.1 (output)
-1.9 to -1.99 to -1.9(output)

How to achieve this in JavaScript?

When the Like/Dislike button is pressed, the counter increases on the first click and decreases on the second

there is a working example of a comment rating. Everything works (when you press like, it’s plus 1, when you press dislike, it’s minus 1) All that needs to be done is to return everything to its original state when the button is pressed again. .

<?
// Checking the id of the evaluated comment received via javascript
if (isset($_POST["comm_id"]) and is_numeric($_POST["comm_id"]))
    $obj = $_POST["comm_id"];
else $obj = '';

// Checking the "rate" sent via JS with a value of 1
if (isset($_POST["rate"]) and ($_POST["rate"] == 0 or $_POST["rate"] == 1))
    $rate = $_POST["rate"];
else $rate = '';

if ($rate != '' and $obj > 0) {
    $rating_plus = 0;
    $rating_minus = 0;

    if ($rating_plus == 0 and $rating_minus == 0) {
        if ($rate == 0) $rating_minus = $rating_minus + 1;
        else $rating_plus = $rating_plus + 1;
    }
    
    else {
        if ($rate == 0) {
            $rating_minus = $rating_minus + 1;
            $rating_plus = $rating_plus - 1;
        } else {
            $rating_minus = $rating_minus - 1;
            $rating_plus = $rating_plus + 1;
        }
        
    }

    //Calculating the rating of a comment

    $sum = $rating_plus - $rating_minus;        
   
    if ($sum < 0) $color_sum = '#865656';
    else {
        $color_sum = '#688656';
        if ($sum == 0) $color_sum = '#888';
    }
    
    $rating_sum = '<b style="color: '.$color_sum.'">'.$sum.'</b>';
    
   // Forming a response
    $output = ['rating_sum' => $rating_sum];
    exit(json_encode($output));
}



//Calculating the rating of a comment
$sum = $Row["plus"] - $Row["minus"];
if ($sum < 0) $comm_rate = '<b style="color: #865656">'.$sum.'</b>';
    else {
        $comm_rate = '<b style="color: #688656">'.$sum.'</b>';
        if ($sum == 0) $comm_rate = '<b style="color: #888">'.$sum.'</b>';
    }
// --/-- //  

$Row["id"] = 4;        
        
$com_rating = '
<div class="rating_com">
    <div class="comm_plus">Like</div>
    <div class="comm_rate" id="rating_comm'.$Row["id"].'">
        '.$comm_rate.'
    </div>
    <div class="comm_minus">Dislike</div>
</div>';


echo '
    <div class="comments" id="m'.$Row["id"].'">
        <div class="com_block">         
            <div class="name">$Name</div>
            <div class="companel">
                '.$com_rating.'
            </div>
            <p>$Row["text"]</p>
    </div>';

?>


<script>
    
document.querySelectorAll('.comm_plus,.comm_minus,.comm_rate').forEach(arm =>{
    arm.addEventListener('click', e => {
        var id_comm = e.target.closest(".comments").getAttribute('id').substr(1); // we get the id of the rated comment and trim the first letter.
        // Check if "comm_plus" was pressed, then the value "1" will be sent to $_POST['rate']
        if (arm.classList.contains("comm_plus")) var num = 1;
        if (arm.classList.contains("comm_minus")) var num = 0;
    
        var xmlhttp = getXmlHttp(); 
        xmlhttp.open('POST', '/news/material', true); 
        xmlhttp.responseType = 'json';
        xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
        xmlhttp.send(`rate=${num}&comm_id=` + encodeURIComponent(id_comm)); 
        xmlhttp.onreadystatechange = function() { 
            if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { 
                const response = xmlhttp.response;               
                var com_rate = document.getElementById(`rating_comm`+id_comm);
                com_rate.classList.add('_active');
    
                setTimeout(() => { 
                    com_rate.classList.remove('_active');
                    com_rate.innerHTML = `${response.rating_sum}`; 
                }, 500);
            }
        };
            
    });
});

// The function creates an XMLHTTP object to send data to a POST request (without using an html form) 
function getXmlHttp() {
    var xmlhttp;
    try {
        xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
    } catch (e) {
        try {
            xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
        } catch (E) {
            xmlhttp = false;
        }
    }
    if (!xmlhttp && typeof XMLHttpRequest!='undefined') xmlhttp = new XMLHttpRequest();
    return xmlhttp;
}

</script>



<style>
.comments {width: 60%; margin: 4em 2em; border: 2px solid grey; border-radius: 10px; padding: 1em}
.com_block .name {display: inline-block; margin: 0 0 7px;}
.com_block .companel {float: right; color: #6A6E68;}
.comment_edit {padding: 6px}
.comment_edit #button {margin-top: 4px}
.rating_com {margin: 0 5px 0 9px}
.rating_com div {display: inline-block}
.comm_minus, .comm_plus {cursor: pointer}
</style>

Using webpack-merge for both module loaders and plugins

We have multiple webpack configuration files, and I need to restructure them to share common configuration

Current file structure

  • webpack.prod.js
  • webpack.dev.js

New file structure

  • webpack.common.js
  • webpack.prod.js
  • webpack.dev.js

The prod and dev files will use webpack-merge to merge their contents with the common file. However, there are a number of places that need different merge rules, and I have been unable to find anything clear about using different merge rules together.

Here is some sample configuration to highlight what I am trying to do

// webpack.common.js

const commonConfig = {

    module: {
        rules: [
            {
                test: /.css$/,
                use: ["css-loader"]
            },
        ]
    },
    plugins: [
            new webpack.EnvironmentPlugin({
                MY_ENV_1: "Common_value_1",
                MY_ENV_2: "Common_value_2",
                MY_ENV_3: "Common_value_3",
            }),
        ],
}

// webpack.dev.js

const devConfig = {

    module: {
        rules: [
            {
                test: /.css$/,
                use: ["style-loader"]
            },
        ]
    },
}

// webpack.prod.js

const prodConfig = {

    module: {
        rules: [
            {
                test: /.css$/,
                use: [MiniCssExtractPlugin.loader,]
            },
        ]
    },
    plugins: [
            new webpack.EnvironmentPlugin({
                MY_ENV_1: "Prod_value_1",
                MY_ENV_2: "Prod_value_2",
            }),
        ],

}

Here are my attempts at merging. As you can see, I have only got as far as doing each individually, as I am not happy with the individual outputs. But I would eventually like to only need a single merge, assuming that is possible.

const { mergeWithRules, mergeWithCustomize, CustomizeRule, unique } = require("webpack-merge");

const merge1 = mergeWithRules({
  module: {
    rules: {
      test: CustomizeRule.Match,
      use: CustomizeRule.Prepend,
    },
  },
})(commonConfig, prodConfig);


const merge2 = mergeWithCustomize({
  customizeArray: unique(
        "plugins",
        ["EnvironmentPlugin"],
        (plugin) => plugin.constructor && plugin.constructor.name,
      ),
  })(commonConfig, prodConfig);

This is the current output I produce.

// merge 1 output - I'm not clear what has happened to the test value
{
    "module": {
        "rules": [
            {
                "test": {},
                "use": [
                    "Resolved/Path/To/loader.js,
                    "css-loader"
                ]
            }
        ]
    },
    "plugins": [
        {
            "keys": [
                "MY_ENV_1",
                "MY_ENV_2",
                "MY_ENV_3"
            ],
            "defaultValues": {
                "MY_ENV_1": "Common_value_1",
                "MY_ENV_2": "Common_value_2",
                "MY_ENV_3": "Common_value_3"
            }
        },
        {
            "keys": [
                "MY_ENV_1",
                "MY_ENV_2"
            ],
            "defaultValues": {
                "MY_ENV_1": "Prod_value_1",
                "MY_ENV_2": "Prod_value_2"
            }
        }
    ]
}

// merge 2 output - only one set of ENV values is used
{
    "module": {
        "rules": [
            {
                "test": {},
                "use": [
                    "css-loader"
                ]
            },
            {
                "test": {},
                "use": [
                    "Resolved/Path/To/loader.js,
                ]
            }
        ]
    },
    "plugins": [
        {
            "keys": [
                "MY_ENV_1",
                "MY_ENV_2"
            ],
            "defaultValues": {
                "MY_ENV_1": "Prod_value_1",
                "MY_ENV_2": "Prod_value_2"
            } // Should also have "MY_ENV_3": "Common_value_3"
        }
    ]
}

How to use paylaod cms Jobs Queue

I am new to paylaod cms & trying to use Jobs Queue, just trying to send email every minute and testing on local machine

here is my payload.config.ts

export default buildConfig({
   jobs: {
    access: {
      run: ({ req }: { req: PayloadRequest }): boolean => {
        // Allow logged in users to execute this endpoint (default)
        if (req.user) return true

        // If there is no logged in user, then check
        // for the Vercel Cron secret to be present as an
        // Authorization header:
        const authHeader = req.headers.get('authorization')
        return authHeader === `Bearer ${process.env.CRON_SECRET}`
      },
    },
    tasks: [
      {
        slug: 'demoTask',
        inputSchema: [
          {
            name: 'time',
            type: 'text',
            required: true,
          },
        ],

        // These are the properties that the function should output
        outputSchema: [
          {
            name: 'text',
            type: 'text',
            required: true,
          },
        ],
        handler: async ({ input, req }) => {
          await req.payload.sendEmail({
            to: '[email protected]',
            subject: 'This is a demoQueue email',
            text: `This is a demoQueue email ${input.time}`,
          })
          return {
            output: {
              text: `${input} loged`,
            },
          }
        },
      },
    ],
    workflows: [
      {
        slug: 'demoWorkflow',
        handler: async ({ job, tasks }) => {
          await tasks.demoTask('1', {
            input: {
              time: `${new Date().toISOString()}`,
            },
          })
        },
        queue: 'demoQueue',
      },
    ],

    autoRun: [
      {
        cron: '* * * * *', // every minute
        limit: 1, // limit jobs to process each run
        queue: 'demoQueue', // name of the queue
      },
    ],
  },
  email: resendAdapter({
    defaultFromAddress: '[email protected]',
    defaultFromName: 'Project Name',
    apiKey: process.env.RESEND_API_KEY!,
  }),
})

but this is not working even I try with command

npx payload jobs:run --queue demoQueue --limit 1

error on the command

MongoNotConnectedError: Client must be connected before running operations

but I check with other operation MongoDB connection working fine
even I try to send email with collection hook “afterChange”, email working fine

can anyone help where I am making mistake

Thanks in advance

css gets transitioned at first mount

I have a svelte app that mounts some progress dots into a pretty plain html site.

simplified the ProgressDots.svelte has this:

hello
<div class="progress-dots">
  <div class="progress-dots__dot"></div>
</div>

<style>
    .progress-dots {
        display: flex;
        justify-content: center;
    }

    .progress-dots__dot {
        width: 10px;
        aspect-ratio: 1 / 1;
        background: #ccc;
        border-radius: 100%;
        transition: background 0.3s ease-in-out
    }
</style>

The problem I am facing is that when the component is first mounted I am getting a transition on the .progress-dots__dot element. It looks like it is going from transparent to #ccc.

I’ve added the hello at the root of the component so that I can verify that it isn’t an opacity effect or something like that on the component. It is just the .progress-dots__dot that is transitioning.

So some potential leads that I’ve found but haven’t been able to verify is that in my built js file it has included the css for the dots, so maybe that isn’t loaded before the element is added?

also when doing a performance recording I am getting this:

enter image description here

Threejs shadow not rendered properly [closed]

shadow not rendered as expected

Why shadows are not rendered properly and there are gradient like issues

const light = new DirectionalLight(tint, 2.5);
light.position.set(-20, 90, 4);
const helper = new CameraHelper(light.shadow.camera);
this.scene.add(helper);
light.castShadow = true;
const factor = 2;
light.shadow.mapSize.width = 512 * factor;
light.shadow.mapSize.height = 512 * factor;
const val = 1000;
light.shadow.camera.left = -val;
light.shadow.camera.right = val;
light.shadow.camera.top = val;
light.shadow.camera.bottom = -val;
light.shadow.camera.near = 0.5;
light.shadow.camera.far = 100;
this.scene.add(light);

Unable to update image name in MySQL database

I am trying to update an image in MySQL database but each time I do try to update, other fields (i.e. location) of the is updated but the image name becomes blank.
Below is the code for updating:

if(isset($_POST['edt_Pic']))
{
    
    $id         = mysqli_real_escape_string($con, $_POST["id"]);
    $file       = mysqli_real_escape_string($con, $_POST['file']);
    $fullname   = mysqli_real_escape_string($con, $_POST['fullname']);
    $filename   = $_FILES['file']['name'];
    $file_temp  = $_FILES['file']['tmp_name'];
    $file_size  = $_FILES['file']['size'];
    
    if($file_size > 1048576)
            {
                echo "<script type='text/javascript'>alert('Attached photo exceeds 1Mb. Kindly reduce the size.');
                        </script>";
                echo "<script>window.location.href='users.php'</script>";
            }
            elseif(!empty($_FILES["file"]["tmp_name"]))
               {
                $exp    = explode(".", $file_name);
                $ext    = end($exp);
                $name   = $_FILES['file']['name'];
                
                move_uploaded_file($_FILES["file"]["tmp_name"],"./users/" . $name);
                
                $location   =   "./users/" . $name;
                
            $sql  = "UPDATE     users
                     SET        file = ?, location = ?, fullname = ?
                     WHERE      id = ?";
            
            $stmt = mysqli_prepare($con, $sql);
              
              mysqli_stmt_bind_param($stmt, "sssi", $file, $location, $fullname, $id);
            
                if(mysqli_stmt_execute($stmt))
                    {
                        echo "<script type='text/javascript'>alert('Image for " . $fullname . " has updated successfully.');
                              </script>";
                        echo "<script>window.location.href='users.php'</script>";
                    } 
                        else                    
                    {
                    echo "<script type='text/javascript'>alert('Oops! Something went wrong. Please try again.');
                            </script>";
                    echo "<script>window.location.href='users.php'</script>";
                }
        }
                 
        mysqli_stmt_close($stmt);
}
mysqli_close($con);

I have tried to add the old file name input field but to no luck.

php inheritance abstract class property [closed]

I have a question about inheritance in php 8.3.
I have an abstract class with a property, variable or what ever it must be called.
I then try to set this property/variable from a function in the abstract class. Then I get an error saying “Undefined variable”
I think that all conventions about OOP has been kept, what am I missing here?

<?php
abstract class grandparent{
    public function somefunction(){
    }
}

abstract class myparent extends grandparent{
    public $prop;
    protected function setfunction($myprop){
        $this->$prop = $myprop;
    }
}

class child extends myparent{
    public function myset() {
        $this->setfunction(42);
        $myvar = $this->prop;
    }
}

$myInstance = new child();
$myInstance->myset();

How to add the another disk folder and files in PHP in XAMPP [closed]

I am connecting the MS Access database with PHP.

My system us a server for XAMPP but the MS Access database is located in another system.

When I use the DSN system for the connection it works well but when I use the DSN-less system doesn’t work and it shows the following error:

32-bit to 64-bit error on DSN system

$conn = odbc_connect('SAP','','');
if($conn)
{ 
echo ""; 
}
else
{ echo "Failed";  }

That why I go for DSN-less system but it does not work outside the root folder.

My DSN system code

$db_username = ''; //username
$db_password = ''; //password


//path to database file
$database_path = realpath('temp.mdb');
print $database_path;
print "<br>";
$database = new PDO("odbc:DRIVER={Microsoft Access Driver (*.mdb, *.accdb)}; DBQ=$database_path; Uid=$db_username; Pwd=$db_password;");


$sql  = "SELECT * FROM Product ORDER BY PCode";
$result = $database->query($sql);
while ($row = $result->fetch()) {
    echo $row["PName"]."<br>";
}

Access drivers code instead of DSN-less system

DSN less Access driver code

In the code above the MS Access database works if it is located in server roor (e.g., C:/XAMPP/HTDOCS/)

I want to access the database in another drive or another computer.