Misaligned frames and images

I’m trying to create a photobooth web application. I’m encountering problems when using custom frames I created.

My problem is that the images and my custom frames are misaligned. I tried to adjust the frames but it also adjust the images so it’s still misaligned. It works perfectly when just choosing colored frames.

image of using my custom frame with the photo strip

Please help me align the frames and my photostrip.

const photoStrip = document.getElementById('photoStrip');
    const photos = JSON.parse(localStorage.getItem('photos')) || [];

    photos.forEach(photo => {
        const img = document.createElement('img');
        img.src = photo;
        photoStrip.appendChild(img);
    });

    // Clear photos from localStorage after displaying
    localStorage.removeItem('photos');

    document.getElementById('downloadBtn').addEventListener('click', () => {
        html2canvas(photoStrip, {
            onrendered: function(canvas) {
                const link = document.createElement('a');
                link.href = canvas.toDataURL('image/png');
                link.download = 'photo_strip.png';
                link.click();
            }
        });
    });

    document.getElementById('retakeBtn').addEventListener('click', () => {
        window.location.href = 'camera.html';
    });

    document.querySelectorAll('.frame, .frame1').forEach(frame => {
        frame.addEventListener('click', () => {
            // Remove selected class from all frames
            document.querySelectorAll('.frame, .frame1').forEach(f => f.classList.remove('selected'));
            // Add selected class to clicked frame
            frame.classList.add('selected');

            const color = frame.getAttribute('data-color');
            const frameSrc = frame.getAttribute('data-frame');

            // Remove existing frame overlay if any
            const existingOverlay = photoStrip.querySelector('.frame-overlay');
            if (existingOverlay) {
                existingOverlay.remove();
            }

            if (frameSrc) {
                photoStrip.style.backgroundColor = 'transparent';
                const overlay = document.createElement('img');
                overlay.src = frameSrc;
                overlay.className = 'frame-overlay';
                photoStrip.appendChild(overlay);

                // Ensure the overlay gets the correct size
                overlay.style.width = "220px";
                overlay.style.height = "740px";

                // Shift photos and photo-strip 10px lower to match custom color positioning
                photoStrip.querySelectorAll('img').forEach(img => {
                    img.style.marginTop = '10px';
                });
                photoStrip.style.marginTop = '-10px';
            } else {
                photoStrip.style.backgroundColor = color;

                // Shift photos and photo-strip 10px lower for custom color
                photoStrip.querySelectorAll('img').forEach(img => {
                    img.style.marginTop = '10px';
                });
                photoStrip.style.marginTop = '10px';
            }
        });
    });

    // Add color picker event listener
    document.getElementById('colorPicker').addEventListener('input', function(e) {
        // Remove selected class from all frames
        document.querySelectorAll('.frame, .frame1').forEach(f => f.classList.remove('selected'));

        // Remove existing frame overlay if any
        const existingOverlay = photoStrip.querySelector('.frame-overlay');
        if (existingOverlay) {
            existingOverlay.remove();
        }

        // Apply the selected color
        photoStrip.style.backgroundColor = e.target.value;

        // Shift photos and photo-strip 10px lower for custom color
        photoStrip.querySelectorAll('img').forEach(img => {
            img.style.marginTop = '10px';
        });
        photoStrip.style.marginTop = '10px';
    });
*{
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}
.banner {
    width: 100%;
    height: 100vh; /* Ensure it occupies the full viewport height */
    background-image: url(bg3.png);
    background-size: cover;
    background-position: center;
    display: flex;
    align-items: flex-start;
    justify-content: center;
    margin: 0; /* Remove any default margin */
    padding: 0; /* Remove any default padding */
    box-sizing: border-box; /* Include padding and border in height calculation */
}
body {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100vh;
    margin: 0; /* Remove default margin */
    padding: 0; /* Remove default padding */
    font-family: 'Cascadia Code', sans-serif;
    overflow: hidden; /* Prevent scrolling if content overflows */
}
.photo-strip {
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 0 !important; /* Remove padding to align the frame properly */
    background-color: #91A6F7;
    margin-right: 20px;
    position: relative;
    width: 220px;
    height: 740px; /* Ensure it matches the frame overlay */
    box-sizing: border-box; /* Include padding and border in height calculation */
    margin-top: 0 !important; /* Ensure it starts at the top */
    z-index: 5; /* Ensure photos are below the frame overlay */
}
.photo-strip img {
    margin: 10px 0;
    width: 200px;
    height: 150px;
    border-radius: 5px;
    z-index: 5; /* Ensure photos are below the frame overlay */
}
#downloadBtn, #retakeBtn {
    font-family: 'Cascadia Code';
    padding: 10px 20px;
    background-color: #91A6F7;
    color: black;
    font-size: 20px;
    width: 175px;
    height: 60px;
    border: none;
    border-radius: 30px;
    cursor: pointer;
    margin: 10px 5px;
}
#retakeBtn {
    background-color: #91A6F7;
}
.frame-options {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 10px;
    margin-bottom: 20px;
    justify-content: center;
}
.frame, .frame1 {
    top: 0;
    width: 60px;
    height: 60px;
    border-radius: 5px;
    cursor: pointer;
    background-size: cover;
    background-position: center;
}
.color-picker-container {
    margin: 10px 0;
    display: flex;
    align-items: center;
    gap: 10px;
}
.color-picker-label {
    font-size: 16px;
    color: black;
}
#colorPicker {
    width: 60px;
    height: 60px;
    padding: 0;
    border: none;
    border-radius: 5px;
    cursor: pointer;
}
.controls {
    display: flex;
    flex-direction: column;
    align-items: center;
    margin-top: 20px; /* Add spacing below the photo strip */
}
.button-row {
    display: flex;
    justify-content: center;
    width: 100%;
}
.frame-overlay {
    position: absolute;
    top: 0; /* Move the frame overlay to the top */
    left: 0;
    width: 220px;
    height: 740px;
    z-index: 10; /* Ensure it's above the photos */
    pointer-events: none; /* Prevent interaction with the frame overlay */
}
<div class="banner">
    <div class="photo-strip" id="photoStrip">
        <!-- Photos will be appended here -->
    </div>
    <div class="controls">
        <div class="frame-options">
            <div class="frame1" style="background-image: url('frames/frame1.png')" data-frame="frames/frame1.png"></div>
        </div>
        <div class="color-picker-container">
            <span class="color-picker-label">Custom Color:</span>
            <input type="color" id="colorPicker" value="#91A6F7">
        </div>
        <button id="downloadBtn">Download</button>
        <button id="retakeBtn">Retake</button>
    </div>
</div>

How can i get customers details when they visit my website, using node js and other npm modules? [closed]

Question:
I have a website, and I want to collect some details about visitors, such as their email, phone number, or company information. My goal is to identify potential customers and improve lead generation.

I have considered the following approaches:

Google Analytics – Tracks user behavior but doesn’t provide personal details.

Lead Capture Forms – Asking users to fill out a form, but many visitors leave without submitting.

Live Chat & Chatbots – Can collect emails, but I want a more passive method.

IP Tracking & Lookup Services – Tools like Clearbit and Leadfeeder claim to identify companies, but I’m unsure how effective they are.

Cookies & Local Storage – Can store data if a user logs in, but new visitors remain anonymous.

Code Attempts:
I tried using express-ip to get the visitor’s IP address:

const express = require("express");
const requestIp = require("request-ip");

const app = express();
app.use(requestIp.mw());

app.get("/", (req, res) => {
    const ip = req.clientIp;
    res.send(`Visitor IP: ${ip}`);
});

app.listen(3000, () => console.log("Server running on port 3000"));

Then, I attempted to fetch company details using Clearbit:

const fetch = require("node-fetch");

async function getCompanyInfo(ip) {
    const response = await fetch(`https://company.clearbit.com/v2/companies/find?ip=${ip}`, {
        headers: {
            Authorization: `Bearer YOUR_CLEARBIT_API_KEY`
        }
    });
    const data = await response.json();
    console.log(data);
}

getCompanyInfo("8.8.8.8"); // Example IP

Questions:
Are there any reliable methods to passively gather visitor details while complying with privacy laws (GDPR, CCPA)?

How can I integrate a service like Clearbit or HubSpot to fetch company details from an IP address?

Is there a way to encourage users to provide their contact details without disrupting their experience?

I’m using React.js for the frontend and Node.js for the backend. Any API recommendations or code examples would be appreciated.

How can i get customers details when they visit my website?

Question:
I have a website, and I want to collect some details about visitors, such as their email, phone number, or company information. My goal is to identify potential customers and improve lead generation.

I have considered the following approaches:

Google Analytics – Tracks user behavior but doesn’t provide personal details.

Lead Capture Forms – Asking users to fill out a form, but many visitors leave without submitting.

Live Chat & Chatbots – Can collect emails, but I want a more passive method.

IP Tracking & Lookup Services – Tools like Clearbit and Leadfeeder claim to identify companies, but I’m unsure how effective they are.

Cookies & Local Storage – Can store data if a user logs in, but new visitors remain anonymous.

Code Attempts:
I tried using express-ip to get the visitor’s IP address:

const express = require("express");
const requestIp = require("request-ip");

const app = express();
app.use(requestIp.mw());

app.get("/", (req, res) => {
    const ip = req.clientIp;
    res.send(`Visitor IP: ${ip}`);
});

app.listen(3000, () => console.log("Server running on port 3000"));

Then, I attempted to fetch company details using Clearbit:

const fetch = require("node-fetch");

async function getCompanyInfo(ip) {
    const response = await fetch(`https://company.clearbit.com/v2/companies/find?ip=${ip}`, {
        headers: {
            Authorization: `Bearer YOUR_CLEARBIT_API_KEY`
        }
    });
    const data = await response.json();
    console.log(data);
}

getCompanyInfo("8.8.8.8"); // Example IP

Questions:
Are there any reliable methods to passively gather visitor details while complying with privacy laws (GDPR, CCPA)?

How can I integrate a service like Clearbit or HubSpot to fetch company details from an IP address?

Is there a way to encourage users to provide their contact details without disrupting their experience?

I’m using React.js for the frontend and Node.js for the backend. Any API recommendations or code examples would be appreciated.

How to make a gallery of images take all available space?

I’m making a project to emulate a pinterest page and the setup is to have the images sorted in 5 columns but the rows should take all the available space depending on the size of each image. I am using js to create all the components and scss to style it.

I have created a div container(.gallery)

.gallery{
height: 100%;
max-height: 1000px;
width: 100%;
display: grid;
grid-template-columns:repeat(5, 1fr);
grid-template-rows: auto;
}.

Inside I have another div for each ‘card’ with another div ‘photo that has the image (from Unsplash) and some buttons.

.card{
@include flex (start, center, column, 5px);
width: 100%;
height: auto;
margin-top: 10px;}

then each image.

.mainImg{
object-fit: cover;
object-position: center;
max-width: 275px;
max-height: 450px;
height: auto;
border-radius: 15px;
};

As it is, the images take 5 columns but the height of each row is the same for all ‘cards’ instead of each taking the space needed based on their actual size. I’ve played around with templaenter code herete-rows, auto-rows but cannot get it to work. Thanks for your help 🙂

myPage

Newbie JS scope question: How do I pass an object’s key/value pair to the outside of an event handler function? [duplicate]

When I console.log(newObject) inside the function as shown, I see newObject and its key/value pair. However, when I console.log outside the function, I see an empty newObject. How do I pass newObject‘s key/value pair to the outside of the function?

let newObject = {}
document.getElementById("submitButton").addEventListener("click", function () {
  newObject = {firstName: 'John', lastName: 'Doe'}
  console.log(newObject)
})

Are 2 load scripts normal in Livewire?

I have a question about Livewire, im bundling livewire manualy and im seeing 2 load scripts (in the head and at the bottom of the body). im not sure if this is always like this but im not sure. The load scripts are identical so im a bit confused on why this is happening. here is the load script that is being injected twice:

window.addEventListener('load', () => window.setTimeout(() => {
   const makeLink = (asset) => {
       const link = document.createElement('link')

       Object.keys(asset).forEach((attribute) => {
           link.setAttribute(attribute, asset[attribute])
       })

       return link
   }

   const fragment = new DocumentFragment;
   [].forEach((asset) => fragment.append(makeLink(asset)))
   document.head.append(fragment)
}))

Im importing Livewire like this inside my bootstrap.js:

import { Livewire, Alpine } from '../../../../vendor/livewire/livewire/dist/livewire.esm.js';

window.Livewire = Livewire;
window.Alpine = Alpine;

And inside my vite.config.js im resolving Livewire:

resolve: {
    alias: {
        livewire: path.resolve(__dirname, 'vendor/livewire/livewire/dist/livewire.esm.js')
    }
},

And chunking Livewire into the core chunk:

manualChunks: {
   "core": ["axios", "livewire"],
   "vendor": ["bootstrap"],
   "charts": ["d3"]
},

Does enyone know why this happens and if its a problem?

If this is a problem how can i fix it, thanks in advance for any insight.

Not able to access POST params in PHP when called from JS [closed]

I have created a very simple PHP file as displayed below.

If I call the API using postman, it works fine and prints the value of “a”.
But when I call through my javascript code, it only returns “……..>>>>>>>” but not the value of “a”.

header("Access-Control-Allow-Origin: *");
header('Access-Control-Allow-Methods: GET, POST');
header("Access-Control-Allow-Headers: content-type,x-requested-with");
echo "........>>>>>>>";
$name = $_POST['a'];
echo $name;

Javascript code

fetch(url, {
method: "POST",
body: JSON.stringify(attrObj),
headers: {
"Content-type": "application/json",
},
})
.then((response) => response.json())
.then((json) => callback.call(obj, json));

Not able to access POST params in PHP when called from JS

I have created a very simple PHP file as displayed below.

If I call the API using postman, it works fine and prints the value of “a”.
But when I call through my javascript code, it only returns “……..>>>>>>>” but not the value of “a”.

header("Access-Control-Allow-Origin: *");
header('Access-Control-Allow-Methods: GET, POST');
header("Access-Control-Allow-Headers: content-type,x-requested-with");
echo "........>>>>>>>";
$name = $_POST['a'];
echo $name;

Javascript code

fetch(url, {
method: "POST",
body: JSON.stringify(attrObj),
headers: {
"Content-type": "application/json",
},
})
.then((response) => response.json())
.then((json) => callback.call(obj, json));

google appscript based webapp is not giving results. frontend is receiving null from the backend, even though the backend is returning valid results [duplicate]

I want to create a simple web app to search a database.
google app-script based webapp is not giving results.
The issue is that the frontend is receiving null from the backend, even though the backend is returning valid results (as shown in the Execution Log).
i have tried with hard coded result, that it is showing, but not result from the search.
My index.html file is as below.

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <style>
      body { font-family: Arial, sans-serif; margin: 20px; }
      input, select, button { margin: 5px; padding: 10px; }
      table { width: 100%; border-collapse: collapse; margin-top: 20px; }
      th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
      th { background-color: #f2f2f2; }
    </style>
  </head>
  <body>
    <h1>Book Search</h1>
    <input type="text" id="searchTerm" placeholder="Enter search term">
    <select id="category">
      <option value="">Select a category</option> <!-- Default option -->
    </select>
    <button onclick="search()">Search</button>

    <table id="results">
      <thead>
        <tr>
          <th>Timestamp</th>
          <th>Date of Addition</th>
          <th>Acc No</th>
          <th>Book Title</th>
          <th>Author</th>
          <th>Book Type</th>
          <th>Volume</th>
          <th>Publication House</th>
          <th>Publication Year</th>
          <th>Pages</th>
          <th>Bill No</th>
          <th>Bill Date</th>
          <th>Price</th>
          <th>Condition</th>
          <th>Subject</th>
          <th>Almirah</th>
          <th>Rack</th>
        </tr>
      </thead>
      <tbody>
      </tbody>
    </table>

    <script>
      // Load categories into dropdown
      google.script.run
        .withSuccessHandler((categories) => {
          console.log('Categories from backend:', categories); // Log categories for debugging
          const dropdown = document.getElementById('category');

          if (!categories || categories.length === 0) {
            console.error('No categories found or categories are empty');
            return;
          }

          // Add categories to the dropdown
          categories.forEach(([category]) => {
            const option = document.createElement('option');
            option.value = category;
            option.text = category;
            dropdown.appendChild(option);
          });
        })
        .withFailureHandler((error) => {
          console.error('Error fetching categories:', error);
          alert('An error occurred while loading categories. Please check the console for details.');
        })
        .getCategories();

      // Perform search
      function search() {
        const searchTerm = document.getElementById('searchTerm').value;
        const category = document.getElementById('category').value;

        if (!searchTerm || !category) {
          alert('Please enter a search term and select a category.');
          return;
        }

        console.log('Sending request to backend with:', { searchTerm, category }); // Log request data

        google.script.run
          .withSuccessHandler((results) => {
            console.log('Results from backend:', results); // Log results for debugging
            const tbody = document.querySelector('#results tbody');
            tbody.innerHTML = ''; // Clear previous results

            if (!results || results.length === 0) {
              tbody.innerHTML = '<tr><td colspan="17">No results found.</td></tr>';
              return;
            }

            // Ensure results is an array
            if (Array.isArray(results)) {
              results.forEach(row => {
                const tr = document.createElement('tr');
                row.forEach(cell => {
                  const td = document.createElement('td');
                  td.textContent = cell;
                  tr.appendChild(td);
                });
                tbody.appendChild(tr);
              });
            } else {
              console.error('Invalid results format:', results);
              tbody.innerHTML = '<tr><td colspan="17">Invalid results format.</td></tr>';
            }
          })
          .withFailureHandler((error) => {
            console.error('Error:', error);
            alert('An error occurred. Please check the console for details.');
          })
          .searchBooks(category, searchTerm);
      }
    </script>
  </body>
</html>

My code.gs file is as below

function doGet() {
  return HtmlService.createHtmlOutputFromFile('index');
}

function getCategories() {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Category');
  if (!sheet) {
    console.error('Category sheet not found');
    return [];
  }
  const data = sheet.getRange(2, 1, sheet.getLastRow() - 1, 2).getValues(); // Skip header row
  console.log('Categories:', data); // Log categories for debugging
  return data;
}

function searchBooks(category, searchTerm) {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const categorySheet = ss.getSheetByName('Category');
  const booksSheet = ss.getSheetByName('Books');

  if (!categorySheet || !booksSheet) {
    console.error('Sheets not found');
    return []; // Return an empty array if sheets are not found
  }

  // Get column number for the selected category
  const categories = categorySheet.getRange(2, 1, categorySheet.getLastRow() - 1, 2).getValues();
  const columnNumber = categories.find(([cat]) => cat === category)?.[1];

  if (!columnNumber) {
    console.error('Invalid category:', category);
    return []; // Return an empty array if category is invalid
  }

  // Search the Books sheet
  const booksData = booksSheet.getRange(2, 1, booksSheet.getLastRow() - 1, booksSheet.getLastColumn()).getValues();
  const results = booksData
    .filter(row => row[columnNumber - 1].toString().toLowerCase().includes(searchTerm.toLowerCase()))
    .map(row => row.map(cell => cell || '')); // Replace null/undefined with empty strings

  console.log('Search results:', results); // Log results for debugging
  return results;
}

THIS IS MY GOOGLE SHEET FILE
https://docs.google.com/spreadsheets/d/1jBkZie2i3Xnt1DGYL0ChAZmSgbseq_nE6V7FzqLLJ3g/edit?usp=sharing

Healthkit framework in Windows? [closed]

Is it possible to develop a native iOS app using HealthKit on Windows?
I want to create a native app that fetches data from HealthKit, but I only have a Windows PC and an iPhone. I understand that Xcode is required for iOS development, but I am looking for any possible workarounds.

What I have tried:
-Looking into Expo Go, but it doesn’t support HealthKit.
-Checking cloud Mac services, but I prefer a free solution.
-Is there any way to build and test an iOS app with HealthKit without a Mac?

Charts.js tooltip position not working properly on Zoom In

I have created a React Application.I was working on dasboard page, in which i have used chart.js for displaying data in Barchart,Pie Chart.All things was working fine,but when i try to zoom in the browser, the tooltip of the Bachart not showing properly, means when i move the cursor to the bar tooltip didn’t get displayed.but when i move the cursor to a specific point it get displayed.I am getting recursion error when i try to use the postioning function inside tooltip.
Do u have any suggestions for me . It will be a great help for me .

tooltip: {
backgroundColor: “rgba(0, 0, 0, 0.7)”,
titleFont: {
size: 12,
weight: “bold”,
},
bodyFont: {
size: 10,
},
footerFont: {
size: 8,
},
callbacks: {
label: function (tooltipItem) {
return ${tooltipItem.label}: ${tooltipItem.raw};
},
},
position: function (context) {
try {
if (!context || !context.tooltip || !context.chart) {
return { x: 0, y: 0 };
}

          const { chart, tooltip } = context;

          // Ensure canvas exists before getting bounding box
          if (!chart.canvas) {
            return { x: 0, y: 0 };
          }

          // Get bounding rectangle of the chart canvas
          const canvasRect = chart.canvas.getBoundingClientRect();
          const zoomLevel = zoomLevelRef?.current || 1;

          // Prevent recursion by avoiding unnecessary updates
          const newX = (tooltip.caretX || 0) * zoomLevel + canvasRect.left;
          const newY = (tooltip.caretY || 0) * zoomLevel + canvasRect.top;

          if (Number.isNaN(newX) || Number.isNaN(newY)) {
            return { x: 0, y: 0 }; // Return safe fallback position
          }

          return { x: Math.round(newX), y: Math.round(newY) };
        } catch (error) {
          console.error("Tooltip positioning error:", error);
          return { x: 0, y: 0 }; // Fallback to prevent crash
        }
      },
    },

PHP Leaf framework – db()->lastInsertId() returns “0”

I have issue with PHP Leaf framework database operation which returns “0” instead of last inserted record id.

My PHP version is 8.2.12.

There is a code.

app/routes/__app.php

app()->get('/apiv1/test', function () {
    $res = db()
    ->insert('item_schemas')
    ->params([
        'table_name' => 'hat',
        'created_at' => Carbon::now(),
        'updated_at' => null
    ])->execute();

    $itemSchemaId = db()->lastInsertID();

    response()->json([
        'itemSchemaId' => $itemSchemaId,
        'errors' => $res ? 'No errors' : db()->errors(),
        'res' => $res
    ]);
});

public/index.php

<?php

/*
|--------------------------------------------------------------------------
| Switch to root path
|--------------------------------------------------------------------------
|
| Point to the application root directory so leaf can accurately
| resolve app paths.
|
*/
chdir(dirname(__DIR__));

/*
|--------------------------------------------------------------------------
| Register The Auto Loader
|--------------------------------------------------------------------------
|
| Composer provides a convenient, automatically generated class loader
| for our application. We just need to utilize it! We'll require it
| into the script here so that we do not have to worry about the
| loading of any our classes "manually". Feels great to relax.
|
*/
require dirname(__DIR__) . '/vendor/autoload.php';

/*
|--------------------------------------------------------------------------
| Bring in (env)
|--------------------------------------------------------------------------
|
| Quickly use our environment variables
|
*/
try {
    DotenvDotenv::createUnsafeImmutable(dirname(__DIR__))->load();
} catch (Throwable $th) {
    trigger_error($th);
}

/*
|--------------------------------------------------------------------------
| Load application paths
|--------------------------------------------------------------------------
|
| Decline static file requests back to the PHP built-in webserver
|
*/
if (php_sapi_name() === 'cli-server') {
    $path = realpath(__DIR__ . parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH));

    if (is_string($path) && __FILE__ !== $path && is_file($path)) {
        return false;
    }

    unset($path);
}

/*
|--------------------------------------------------------------------------
| Attach blade view
|--------------------------------------------------------------------------
|
| Templating has been disabled because you chose the MVC for APIs starter.
| If you want to use blade in your application,
| you can uncomment the line below.
|
*/
// LeafConfig::attachView(LeafBlade::class);

/*
|--------------------------------------------------------------------------
| Load Leaf configuration
|--------------------------------------------------------------------------
|
| Leaf MVC allows you to customize Leaf and it's modules using
| configuration files defined in the config folder. This line
| loads the configuration files and makes them available to
| your application.
|
*/
LeafCore::loadApplicationConfig();




/*
|--------------------------------------------------------------------------
| Sync Leaf Db with ORM and connect
|--------------------------------------------------------------------------
|
| Sync Leaf Db with ORM and connect to the database
| This allows you to use Leaf Db without having
| to initialize it in your controllers.
|
| If you want to use a different connection from those
| used in your models, you can remove the line below and
| add your own connection with:
| db()->connect(...)
|
| **Uncomment the line below to use Leaf Db**
| **You don't need this line to use Leaf Auth**
*/

db()->autoConnect();

/*
|--------------------------------------------------------------------------
| Load custom libraries
|--------------------------------------------------------------------------
|
| You can load your custom libraries here. If you have
| anything defined in your lib folder, you can load
| them here. Simply uncomment the line below.
|
*/
// LeafCore::loadLibs();

/*
|--------------------------------------------------------------------------
| Run your Leaf MVC application
|--------------------------------------------------------------------------
|
| This line brings in all your routes and starts your application
|
*/

LeafCore::runApplication();

composer.json

{
    "name": "leafs/mvc",
    "version": "3.9.1",
    "description": "A lightweight PHP MVC framework powered by Leaf",
    "type": "library",
    "keywords": [
        "framework",
        "leaf",
        "leafPHP",
        "mvc",
        "leaf mvc"
    ],
    "license": "MIT",
    "authors": [
        {
            "name": "Michael Darko",
            "email": "[email protected]",
            "homepage": "https://mychi.netlify.app",
            "role": "Maintainer"
        },
        {
            "name": "Abdulbasit Rubeya",
            "email": "[email protected]",
            "homepage": "https://github.com/ibnsultan",
            "role": "Maintainer"
        }
    ],
    "require": {
            "leafs/blade": "*",
            "leafs/mvc-core": "^1.11",
            "leafs/leaf": "^3.7",
            "leafs/csrf": "*",
            "leafs/logger": "v2.0",
            "leafs/cors": "*",
            "leafs/auth": "^3.0",
            "leafs/db": "*",
            "leafs/vite": "^0.3.0",
            "leafs/form": "^3.0",
            "leafs/http": "^3.0",
            "leafs/aloe": "^2.3",
            "leafs/fs": "v2.0"
    },
    "require-dev": {
        "fakerphp/faker": "^1.16",
        "leafs/alchemy": "^2.0"
    },
    "autoload": {
        "psr-4": {
            "App\": "app/",
            "Tests\": "tests/",
            "Config\": "config/",
            "App\Http\": "app/http/",
            "App\Jobs\": "app/jobs/",
            "App\Lang\": "app/lang/",
            "App\Mail\": "app/mail/",
            "App\Views\": "app/views/",
            "App\Utils\": "app/utils/",
            "App\Events\": "app/events/",
            "App\Models\": "app/models/",
            "App\Mailers\": "app/mailers/",
            "App\Workers\": "app/workers/",
            "App\Console\": "app/console/",
            "App\Scripts\": "app/scripts/",
            "App\Helpers\": "app/helpers/",
            "App\Channels\": "app/channels/",
            "App\Services\": "app/services/",
            "App\Middleware\": "app/middleware/",
            "App\Components\": "app/components/",
            "App\Controllers\": "app/controllers/",
            "App\Notifications\": "app/notifications/",
            "App\Database\Seeds\": "app/database/seeds/",
            "App\Database\Schema\": "app/database/schema/",
            "App\Database\Factories\": "app/database/factories/"
        },
        "exclude-from-classmap": [
            "app/database/migrations"
        ]
    },
    "config": {
        "optimize-autoloader": true,
        "sort-packages": false,
        "allow-plugins": {
            "pestphp/pest-plugin": true
        }
    },
    "scripts": {
        "post-root-package-install": [
            "@php -r "file_exists('.env') || copy('.env.example', '.env');"",
            "@php -r "if (file_exists('README2.MD')) {unlink('README.MD'); rename('README2.MD', 'README.MD');}""
        ],
        "post-create-project-cmd": [
            "@php leaf key:generate"
        ]
    },
    "minimum-stability": "dev",
    "prefer-stable": true
}

app/database/migrations/2025_03_18_075024_create_item_schema.php

<?php

use LeafDatabase;
use IlluminateDatabaseSchemaBlueprint;

class CreateItemSchema extends Database
{
    /**
     * Run the migrations.
     * @return void
     */
    public function up()
    {
        if (!static::$capsule::schema()->hasTable('item_schemas')) :
            static::$capsule::schema()->create('item_schemas', function (Blueprint $table) {
                $table->id();
                $table->string('table_name')->unique();
                $table->timestamp('created_at')->nullable();
                $table->timestamp('updated_at')->nullable();
            });
        endif;
    }

    /**
     * Reverse the migrations.
     * @return void
     */
    public function down()
    {
        static::$capsule::schema()->dropIfExists('item_schemas');
    }
}

all composer packages after command

composer show -i

carbonphp/carbon-doctrine-types  2.1.0    Types to use Carbon in Doctrine
doctrine/cache                   2.2.0    PHP Doctrine Cache library is a popular cache implementation that suppor...
doctrine/dbal                    3.9.4    Powerful PHP database abstraction layer (DBAL) with many features for da...
doctrine/deprecations            1.1.4    A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 loggin...
doctrine/event-manager           2.0.1    The Doctrine Event Manager is a simple PHP event system that was built t...
doctrine/inflector               2.0.10   PHP Doctrine Inflector is a small library that can perform string manipu...
fakerphp/faker                   v1.24.1  Faker is a PHP library that generates fake data for you.
firebase/php-jwt                 v6.11.0  A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Shou...
graham-campbell/result-type      v1.1.3   An Implementation Of The Result Type
illuminate/bus                   v8.83.27 The Illuminate Bus package.
illuminate/collections           v8.83.27 The Illuminate Collections package.
illuminate/container             v8.83.27 The Illuminate Container package.
illuminate/contracts             v8.83.27 The Illuminate Contracts package.
illuminate/database              v8.83.27 The Illuminate Database package.
illuminate/events                v8.83.27 The Illuminate Events package.
illuminate/filesystem            v8.83.27 The Illuminate Filesystem package.
illuminate/macroable             v8.83.27 The Illuminate Macroable package.
illuminate/pipeline              v8.83.27 The Illuminate Pipeline package.
illuminate/support               v8.83.27 The Illuminate Support package.
illuminate/view                  v8.83.27 The Illuminate View package.
jenssegers/blade                 v1.4.0   The standalone version of Laravel's Blade templating engine for use outs...
leafs/alchemy                    2.2      Integrated testing/style fixing tool for your PHP apps
leafs/aloe                       2.5.1    Overpowered command line tool for your leaf apps.
leafs/anchor                     v1.6.2   Leaf PHP util module
leafs/auth                       v3.4.1   Leaf PHP auth helper
leafs/blade                      v4.0     Leaf PHP Framework adaptation of jenssegers/blade package
leafs/cors                       v1.2     Leaf PHP cors config
leafs/csrf                       v0.5.4   Leaf CSRF security patch for leaf anchor
leafs/date                       v2.2     Leaf PHP date module
leafs/db                         v4.0.1   Leaf PHP db module.
leafs/exception                  v3.6.3   Error handler for leaf (fork of whoops)
leafs/form                       v3.2     Simple straightup data validation
leafs/fs                         v2.0     Leaf PHP session + flash modules
leafs/http                       v3.5     Http abstraction for Leaf PHP
leafs/leaf                       v3.12    Elegant PHP for modern developers
leafs/logger                     v2.0     Leaf PHP logger utility
leafs/mvc-core                   v1.11.1  Core files specific to MVC based leaf frameworks like Leaf MVC and Leaf ...
leafs/password                   v1.0     Leaf PHP password helper
leafs/session                    v4.0.1   Leaf PHP session + flash modules
leafs/vite                       v0.3.0   Server component for Vite
nesbot/carbon                    2.73.0   An API extension for DateTime that supports 281 different languages.
nikic/php-parser                 v4.19.4  A PHP parser written in PHP
phpoption/phpoption              1.9.3    Option Type for PHP
psr/cache                        3.0.0    Common interface for caching libraries
psr/clock                        1.0.0    Common interface for reading the clock.
psr/container                    1.1.2    Common Container Interface (PHP FIG PSR-11)
psr/log                          2.0.0    Common interface for logging libraries
psr/simple-cache                 1.0.1    Common interfaces for simple caching
psy/psysh                        v0.11.22 An interactive shell for modern PHP.
symfony/console                  v5.4.47  Eases the creation of beautiful and testable command line interfaces
symfony/deprecation-contracts    v3.5.1   A generic function and convention to trigger deprecation notices
symfony/finder                   v5.4.45  Finds files and directories via an intuitive fluent interface
symfony/polyfill-ctype           v1.31.0  Symfony polyfill for ctype functions
symfony/polyfill-intl-grapheme   v1.31.0  Symfony polyfill for intl's grapheme_* functions
symfony/polyfill-intl-normalizer v1.31.0  Symfony polyfill for intl's Normalizer class and related functions
symfony/polyfill-mbstring        v1.31.0  Symfony polyfill for the Mbstring extension
symfony/polyfill-php73           v1.31.0  Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions
symfony/polyfill-php80           v1.31.0  Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions
symfony/process                  v6.4.19  Executes commands in sub-processes
symfony/service-contracts        v3.5.1   Generic abstractions related to writing services
symfony/string                   v6.4.15  Provides an object-oriented API to strings and deals with bytes, UTF-8 c...
symfony/translation              v6.4.19  Provides tools to internationalize your application
symfony/translation-contracts    v3.5.1   Generic abstractions related to translation
symfony/var-dumper               v6.4.18  Provides mechanisms for walking through any arbitrary PHP variable
symfony/yaml                     v6.4.18  Loads and dumps YAML files
vlucas/phpdotenv                 v5.6.1   Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SE...
voku/portable-ascii              1.6.1    Portable ASCII library - performance optimized (ascii) string functions ...

And result is:

{
  "itemId": "0"
}

MySQL connection is established correct and record is inserted to the database, db()->lastInsertId() should returns valid record Id. Thanks very much for help.

EDIT:

Result after var_dump:

object(PDOStatement)#36 (1) {
  ["queryString"]=>
  string(78) "INSERT INTO item_schemas (table_name,created_at,updated_at) VALUES (?,?,?)"
}

API result:

{
"itemSchemaId": "0",
  "errors": "No errors",
  "res": {
    "queryString": "INSERT INTO item_schemas 
    (table_name,created_at,updated_at) VALUES (?,?,?)"
  }
}

After Explain query:

"query": [
{
  "id": 1,
  "select_type": "INSERT",
  "table": "item_schemas",
  "partitions": null,
  "type": "ALL",
  "possible_keys": null,
  "key": null,
  "key_len": null,
  "ref": null,
  "rows": null,
  "filtered": null,
  "Extra": null
}
],

Explain query:

$query = db()->query("EXPLAIN " . "INSERT INTO item_schemas (table_name,created_at,updated_at) VALUES ('glovesssssssssssssssdsssss','2025-03-23 10:29:29',NULL)")->all();

Table structure with EXPLAIN:

{
"query": [
{
"Field": "id",
"Type": "bigint(20) unsigned",
"Null": "NO",
"Key": "PRI",
"Default": null,
"Extra": "auto_increment"
},
{
"Field": "table_name",
"Type": "varchar(255)",
"Null": "NO",
"Key": "UNI",
"Default": null,
"Extra": ""
},
{
"Field": "created_at",
"Type": "timestamp",
"Null": "YES",
"Key": "",
"Default": null,
"Extra": ""
},
{
"Field": "updated_at",
"Type": "timestamp",
"Null": "YES",
"Key": "",
"Default": null,
"Extra": ""
}
}

How to get isset() to execute MORE than once in PHP? [duplicate]

I’m trying to do something that should be simple. I want a button that every time it’s clicked to update an mysql row value to increment by 1. so click in ten times and the value is 10. I am trying to use isset() to do this, with just normal variables to test:

php:

   $amount = 0;

   if(isset($_POST['button1'])) {
   echo "button 1 clicked";
   $amount++;
   }

html:

<form method="post">
    <input class="button" type="submit" value="select" name="button1"></input>
</form>

<h1><?= $amount ?></h1>

this works, but only once. My thought was that since $_POST[‘button1’] is now set, it doesn’t execute again because it is only supposed to execute when the value is no longer null and that only happens once. so, I thought I’d try:

   unset($_POST[‘button1’]);

in the isset() block, or even:

   $_POST[‘button1’] = null;

so that the button click would hopefully redefine it, but no luck. what do I do? most questions want a button to click only once, but I want the opposite, for it to theoretically click forever. why can’t a button just call a function like in js? I know php probably isn’t the best choice for this kind of project, but is there a way?