Best way to automate SQL dump to CodeIgniter 4 migrations? [closed]

I’m working on a project where I need to convert SQL dump files (e.g., from phpMyAdmin) into CodeIgniter 4 migration files, including foreign keys and triggers. Manually writing migrations is inefficient, especially with complex schemas. Are there tools or best practices for this? I’ve started a GitHub project to address this—any feedback or suggestions?

I started by manually converting a SQL dump file (e.g., from phpMyAdmin) into CodeIgniter 4 migration files using the Forge class, defining tables and foreign keys like user_id with ON DELETE SET NULL. However, this process is time-consuming, especially with complex schemas involving triggers and multiple tables. I explored existing tools like CodeIgniter’s migration system and third-party libraries, but none fully automate the conversion of SQL dumps while preserving foreign key actions (e.g., SET NULL, NO ACTION) and triggers.

I attempted to write a custom script using PHP to parse the SQL file and generate migration code, but handling edge cases (e.g., multi-line SQL, non-standard syntax) proved challenging. I expected a more efficient solution that could read a SQL file, extract table structures, foreign keys, and triggers, and output ready-to-use CodeIgniter 4 migration files with minimal manual adjustment. To address this, I’ve begun developing a GitHub project to automate this process, but I’d like to know if there are better approaches or tools I might have missed.

Admin Toolbar Not Showing on All Pages After Restoring WordPress Backup [closed]

I recently restored my WordPress site to a previous backup (dated yesterday). After the restoration:

The admin toolbar is missing on the homepage.

After some time, it disappeared on all pages of the site.

I am logged in as an administrator, and other admin functionalities are working.

Here are my current environment details:

WordPress version: 6.x.x

PHP version: 8.x

Active theme: Woodmart (premium)

Active plugins: Elementor Pro, Dokan Pro, WooCommerce, LiteSpeed Cache, WPForms Lite, and others.

Cache / CDN: LiteSpeed Cache + Cloudflare (if relevant)

Cleared browser cache and cookies.

Deactivated all plugins → still no admin toolbar.

Switched to default theme (Twenty Twenty-Three) → admin toolbar appeared.

Checked user roles → administrator.
Why is the admin toolbar missing after restoring the backup?
How can I make it appear again on all pages without affecting the site?

Does Bit Flows Pro limit either the number of nodes executed in a single flow or the maximum duration?

Bit Flows Pro flow stops early (~20–21s) with fewer nodes than expected on WordPress (OpenLiteSpeed + lsphp). Where is the timeout coming from and how do I raise it?

Environment

  • WordPress + Bricks Builder
  • JetEngine (CCTs + Relations), JetFormBuilder (form + repeater)
  • Bit Flows Pro (flows triggered by webhook)
  • RunCloud server running OpenLiteSpeed with lsphp 8.1 (not PHP-FPM)

What the flow does

A JetFormBuilder form creates 4 CCTs of type “contatos” (x1), “atribuicoes” (x2) and “interacoes” (x1).
Then it sends a webhook to Bit Flows Pro with a repeater array so the flow can create N extra CCTs of type “interacoes“ and all the relations between them. The N extra CCTs and the connections they require are created with Rest API requests.

What I tried

Each repeater item equals a “cycle” of 6 nodes (create interacao, 5 relations).
With the 2 “intro” nodes at the start, a run with 2 items on the repeater should end with 14 nodes. A run with 3, with 20 nodes and so on.

If I have 3 items on the repeater, everything works fine, with the run ending with 20 nodes at around 19-20s. When I try to add a fourth item do the repeater, the run ends early with around 21 nodes, status SUCCESS, and duration ~19–21s.

The logs show no errors, both the Bit Flows Pro logs and the WP debug log.

What I suspect

A hard timeout based on the number of nodes or on ~20s (runner/job timeout) is aborting the flow before the final node(s), even though the flow UI shows “SUCCESS”.

Bit Flows Pro log inside the flow

Flow I built

Expected 2 arguments. Found 1.intelephense(P1005) [closed]

Good evening,

I am a beginner in web developpement and I am stuck beacause when i write thoses lines :

$produit->setCategorie($this->getReference(CategorieFixtures::INFORMATIQUE));

$produit->setCategorie($this->getReference(CategorieFixtures::ELECTROMENAGER));

There is always a red line saying that it expect 2 arguments and I only have one.

On the Online courses it works, but on my computer nothing.

And when I try this commande on my Terminal : php bin/console doctrine:fixtures:load

it says :

Too few arguments to function
DoctrineCommonDataFixturesAbstractFixture::getReference(), 1 passed
in
C:xampphtdocssymfony-sitewebsrcDataFixturesProduitFixtures.php
on line 17 and exactly 2 expected

I hope I was clear.

Here is a picture of my code :
enter image description here

I tried to install the vers 1.2.3 version of PHP but it still did not worked. Even after I reboot my VSCODE.

Then I tried to put in false all the “intelephense” on the JSON file. I rebooted my VSCODE still nothing.

And I tried to empty the cache, then I rebooted my VSCODE and nothing works.

Google Maps v3 can’t delete marker

When I push the AdvancedMarker to an array, it then later on will not delete but I can clearly see that when it finds the marker in the array it is an element.

const markerToRemove = activeMarkers.find(m => m.title === imei);
if (markerToRemove)
{
    console.log(markerToRemove)
    markerToRemove.remove();

    activeMarkers = activeMarkers.filter(m => m !== markerToRemove);
    console.log(`Removed existing marker with IMEI: ${imei}`);
} else
{
    console.log(`No marker found with IMEI: ${imei}`);
}
const marker = new google.maps.marker.AdvancedMarkerElement({
    map,
    position: { lat: latitude, lng: longitude },
    content: el,
    title: imei,
});

marker.imei = imei; // Store IMEI for identification
activeMarkers.push(marker);

Any help would be appreciated!

I tried creating a new webpage and starting again and this did not fix the problem. I expected it to remove the marker.

How to make Jest depend on other test?

In PHPUnit, there is Test dependencies feature but in Jest I don’t see any like that.

I have tests just like this. (The whole Node.js project is in "type": "module".)

import fs from 'node:fs';

describe('Description of test file 1', () => {
    test('Test on file1', () => {
        expect(true).toBeTruthy();
        // create file for use in file2. also use it for test here too.
    });
});

Above is file1.test.mjs.

import fs from 'node:fs';

describe('Description of test file 2', () => {
    test('Test on file2', () => {
        expect(false).toBeFalsy();
        // use a file that created in file1. test it then delete.
    });
});

Above is file2.test.mjs.

I want to make sure that file2.test.mjs runs after file1.test.mjs.
How to mark it to run after file 1 (or also know in PHPUnit as depends on file1)?

How to hide only the progress bar in YouTube IFrame (controls:1) and still allow quality selection?

I’m embedding a YouTube video using the IFrame Player API.
I want to hide only the progress bar (seek bar) but still allow users to change video quality via the gear icon.

I tried using controls: 0, but it hides the entire YouTube UI, including the quality selector.

Setting controls: 1 shows everything, but I only want to keep the quality menu and remove the timeline/progress bar.

Also, using CSS like this doesn’t work:

iframe .ytp-progress-bar {
  display: none !important;
}

Because the iframe is cross-origin, I can’t access or style the internal elements of the player.

Is there any way to hide just the progress bar while keeping the quality selector visible?
Even a hacky workaround would be appreciated.

What I’ve tried:

playerVars.controls = 0 → hides everything, including quality menu

playerVars.controls = 1 + CSS mask → can’t style inside iframe

setPlaybackQuality('hd1080') → deprecated / doesn’t work

My goal:

Hide only the timeline/progress bar

Keep the quality menu available (or programmatically set video quality)

Any ideas, tricks, or workarounds?

Thanks in advance!

DOM vs Canvas performance for bullet comments (danmaku). Do I really need WebGL?

I’m building a danmaku (bullet comments) system in a project that consists of HTML + CSS + TypeScript.
So far, I’ve tried two approaches:

Direct DOM manipulation

I create <div> or <img> elements for each danmaku.

Position updates are done using CSS transform: translate3d(...) for smooth GPU acceleration.

Performance is actually quite good, but I still see some unavoidable jitter/shaking when many elements are moving, especially with <img> tags.

Canvas 2D API

I render all danmaku on a <canvas>.

Surprisingly, this feels slower than DOM: more stuttering and even screen tearing/flickering.

Even with an offscreen buffer (OffscreenCanvas or double buffering), it doesn’t feel as smooth as DOM.

I also considered a third approach:

Pre-render each danmaku’s text into a small <canvas> once.

Later, just drawImage those cached canvases every frame instead of calling fillText.

But I’m worried this might introduce too much complexity and memory overhead if there are many comments.

Now I’m wondering:

Is this just the limitation of Canvas 2D API, and the only way to get smooth danmaku rendering at scale is WebGL?

Or are there known techniques to make Canvas-based text/images perform as well as DOM (e.g., caching, texture atlas, bitmap reuse)?

In practice, what do large-scale video platforms (like Bilibili, Niconico) use for this?

Any advice or references would be appreciated!

Following JavaScript code works on desktop version of Firefox, Safari and Chrome but does not on the iPhone version of Firefox, Safari

Following JavaScript code works on desktop version of Firefox, Safari and Chrome but does not on the iPhone version of Firefox, Safari.

const jsDate = new Date();
const year = jsDate.getFullYear();
const month = jsDate.getMonth() + 1;
const day = jsDate.getDate();
const start = new Date(`${year}-${month}-${day}`);
console.log('start', start);

How to hide/handle google one tap when inside a mobile in app browser?

Similar to this , google one tap sign in for my site, when inside a 3rd party mobile app’s in app browser (e.g. instagram, youtube, etc) will silently fail with a white screen.

This not being supported is an intentional behavior

What is the best way to handle this situation for a better user experience? As per google’s recommendation the 3rd party mobile apps should defer to using the system browser instead. But that isn’t in our control as our site could be opened/navigated to by the in-app browser.

Non-viable solutions I’ve searched:

  • Hiding google one tap based on user agent isn’t viable, as there’s no standardized user agent property to check if it’s an in app browser (see an attempt at https://github.com/f2etw/detect-inapp/blob/master/src/inapp.js)
  • Check viewport if the browser is mobile,but this doesn’t discriminate if it’s a system browser (which would work fine) or in app browser (which fails)

Why is it when I manually line break my code is fine but on auto line break my connecting logic breaks?

Basically I have a neon customisation website where customers can text in any text they want and see it on a live preview canvas, one of my backboard options – cut to shape, adds an ‘acrylic’ backboard behind my neon. The problem is there’s a connector that connects inbetween lines to make the backboard like one unified body, now the issue is when I align text center or right (default is left) when the text soft line wraps (automatically due to width restraint), the connector is confused when I tap align right or center to the whole text and protrudes out on the left hand side making a sharp shape that sticks out where it should curve downwards. On manual (enter) line breaks, the logic works perfectly and the connector is smooth on either side whether it’s left, center or right, why is that?

I tried everything by changing the math of the connector but I don’t think the curve is the issue, I think the issue is that it can’t discern between auto vs manual and has different logic for each (a given because it gets the bounding client to measure actual text width after a soft line wrap)

How do I make a draggable image when on zoom: it stops at edge of the window (JS, jQuery)

I am making an Image Viewer for my website for when on zoom and when on drag, it will stops at the edge of the window (will not pull more further) and all I tried wasn’t working as expected. This is the current I have

HTML

<div id="imageModal">
      <div id="blackout"></div>
      <span class="close"></span>
      <div id="modalImage">
        <div id="containerLimit">
          <img src="">
        </div>
      </div>
    </div>

CSS

/* Modal blackout background */
#imageModal {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.2s ease, visibility 0.2s ease;
    z-index: 240009;
}

#blackout {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: #000000c0;
    opacity: 0;
    transition: opacity 0.2s ease;
}

.imgauto:hover, .imgautofull:hover {
  cursor: pointer;
}

/* When the modal is active */
#imageModal.show #blackout {
    opacity: 1;
}
#imageModal.show {
    opacity: 1;
    visibility: visible;
}

/* Modal content (image box) */
.modal-content {
    position: relative;
    border-radius: 10px;
    max-width: 90%;
    max-height: 90%;
    display: flex;
    justify-content: center;
    align-items: center;
}

/* The full-size image */
#modalImage {
    position: fixed;
    z-index: 240010;
    transform: scale(0.9);
    transition: 0.2s ease;
    margin: 50px;
    display: flex;
    align-items: center;
    justify-content: center;
}

#modalImage img {
    position: relative;
    max-width: 80%;
    max-height: 80vh;
    transition: 0.2s ease;
    border-radius: 0px;
}

#imageModal.show #modalImage {
    transform: scale(1);
}

/* Close button */
.close {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    color: white;
    z-index: 1;
}

.img-zoom {
  cursor: grab;
  transform: scale(2);
  /*width: auto;*/
  /*height: auto;*/
  /*max-width: none;*/
}

.img-zoom:active {
  cursor: grabbing;
}

#modalImage, #containerLimit {
  position: fixed;
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
}

#containerLimit img {
  pointer-events: auto; 
}

JS

// imgauto
document.addEventListener("DOMContentLoaded", function () {
    const modal = document.getElementById("imageModal");
    const modalImg = document.getElementById("modalImage");
    const inImg = modalImg.querySelector("img");
    const closeBtn = document.querySelector(".close");

    // Select all images with the class 'imageToView'
    const imageContainers = document.querySelectorAll(".imgauto, .imgautofull");

    imageContainers.forEach(container => {
        const img = container.querySelector("img"); // Get the image inside each div
    
        if (!img) return; // Skip if no image inside the div
    
        container.addEventListener("click", function () {
            modal.style.display = "flex";
            setTimeout(() => modal.classList.add("show"), 10);
            inImg.src = img.src;
            document.body.classList.add("modal-open");
        });
    });

    closeBtn.addEventListener("click", function () {
        closeModal();
    });

    modal.addEventListener("click", function (e) {
        if (e.target === modal) {
            closeModal();
        }
    });
    
    let isDragging = false;
    let zoomed = false;
    
    function closeModal() {
        modal.classList.remove("show");
        inImg.classList.remove('img-zoom');
        disableDrag("#modalImage img");
        isDragging = false;
        zoomed = false;
        setTimeout(() => {
            modal.style.display = "none";
            document.body.classList.remove("modal-open");
        }, 300); // Match the transition duration
    }
    
    // drag on zoom

    let sX, sY;
    const dragFound = 5; // pixels before it's considered drag

    
    function updateContainer() {
        const ww = window.innerWidth;
        const wh = window.innerHeight;
        
        console.log("-----------------------------------------");
        console.log(`WINDOW: width: ${ww} height: ${wh}`);
      
        // inImg.addEventListener("transitionend", updateContainer, { once: true });
        // const rect = inImg.getBoundingClientRect();
        // const bw = rect.width;
        // const bh = rect.height;
        // console.log(`IMAGE: width: ${bw} height: ${bh}`);
        
        modalImg.style.width = ww + 'px';
        modalImg.style.height = wh + 'px';
      
        console.log(`MASK: width: ${ww} height: ${wh}`);
      
        const cont = document.getElementById("containerLimit");
        cont.style.width = ww + "px";
        cont.style.height = wh + "px";
    }
    
    imageContainers.forEach(container => {
        const img = container.querySelector("img"); // Get the image inside each div
    
        if (!img) return; // Skip if no image inside the div
    
        container.addEventListener("click", function () {
            updateContainer();
        });
    });
    
    // function enableDrag() {
    //     $(inImg).draggable({
    //         // containment: "#containerLimit",
    //         // scroll: false,
    //         // drag: function(event, ui) {
    //         //     if (ui.position.top > 0) {
    //         //         ui.position.top = 0;
    //         //     }
    //         //     var maxtop = ui.helper.parent().height() - ui.helper.height();
    //         //     if ( ui.position.top < maxtop) {
    //         //         ui.position.top = maxtop;
    //         //     }
    //         //     if ( ui.position.left > 0) {
    //         //         ui.position.left = 0;
    //         //     }
    //         //     var maxleft = ui.helper.parent().width() - ui.helper.width();
    //         //     if ( ui.position.left < maxleft) {
    //         //         ui.position.left = maxleft;
    //         //     }
    //         // }
    //         containment: "window"
    //     });
    // }
    
    function enableDrag(selector, maskSelector) {
        let $img = $(selector);
        let $mask = $(maskSelector);
        
        if ($img.length === 0 || $mask.length === 0) {
            console.error("Error: One or both of the elements were not found.");
            return;
        }
        console.log("FUNCTION: [jQuery draggable] USE");
    
        $img.css({top:0, left:0});
        
        // disableDrag(selector); // prevent duplicates
        // Cache dimensions to improve performance during drag
        let maskWidth = $mask.width();
        let maskHeight = $mask.height();
        // let imgPos = $img.offset();
        let imgWidth = $img.width();
        let imgHeight = $img.height();
        
        // console.log("mw, mh: ", maskWidth, maskHeight);
        // console.log("ip: ", imgPos);
        // console.log("iw, ih: ", imgWidth, imgHeight);
    
        // Calculate bounds
        let minLeft = maskWidth - imgWidth;
        let maxLeft = 0;
        let minTop = maskHeight - imgHeight;
        let maxTop = 0;
        // let x1 = (imgPos.left + maskWidth) - imgWidth;
        // let y1 = (imgPos.top + maskHeight) - imgHeight;
        // let x2 = imgPos.left;
        // let y2 = imgPos.top;
        
        // console.log("x1, y1: ", x1, y1);
        // console.log("x2, y2: ", x2, y2);
        $img.draggable({
            drag: function(event, ui) {
                // Constrain the position
                ui.position.left = Math.min(maxLeft, Math.max(minLeft, ui.position.left));
                ui.position.top = Math.min(maxTop, Math.max(minTop, ui.position.top));
            }
        });
        
        // $img.draggable({
        //     containment: [x1, y1, x2, y2]
        // });
    }
    
    function disableDrag(selector = "#inImg") {
        let $img = $(selector);
        if ($img.draggable("instance")) {
            console.log("FUNCTION: [jQuery draggable] DESTROY");
            $img.draggable("destroy");
        } else {
            console.log("FUNCTION: [jQuery draggable] No draggable instance found for", selector);
        }
    }
    
    // Mouse events
    modalImg.addEventListener("mousedown", function (e) {
        sX = e.clientX;
        sY = e.clientY;
        isDragging = false;
    });
    
    modalImg.addEventListener("mousemove", function (e) {
        if (e.buttons === 1) {
            const currentX = e.clientX;
            const currentY = e.clientY;
            const distance = Math.sqrt(
                Math.pow(currentX - sX, 2) + Math.pow(currentY - sY, 2)
            );
        
            if (distance > dragFound) {
                isDragging = true;
                enableDrag("#modalImage img", "#containerLimit");
                console.log("MOUSE EVENT: Dragging");
            }
        }
    });
    
    modalImg.addEventListener("mouseup", function () {
        if (!isDragging) {
            // Toggle zoom on click
            zoomed = !zoomed;
            if (zoomed) {
                inImg.classList.add("img-zoom");
          
                // Enable draggable when zoomed
                enableDrag("#modalImage img", "#containerLimit");
            } else {
                inImg.classList.remove("img-zoom");
          
                // Disable draggable when zoomed out
                disableDrag("#modalImage img");
          
                // Reset to original position
                inImg.style.left = "0px";
                inImg.style.top = "0px";
                inImg.style.transform = ""; // optional: clear inline transforms
            }
        
            requestAnimationFrame(() => updateContainer());
        } else {
            // Drag release – keep zoomed in
            if (!zoomed) {
                zoomed = true;
                inImg.classList.add("img-zoom");
          
                enableDrag("#modalImage img", "#containerLimit");
          
                requestAnimationFrame(() => updateContainer());
            }
        }
        isDragging = false;
    });
    
    // Update container size when window resizes
    window.addEventListener("resize", () => {
        updateContainer();
    });
});

NOTE: I have made a comment on some of the code in JS because I might re-use it in some cases.

The current code I have is that when on zoom and when on drag, it will enable draggable. But the result is the draggable element stays still as it is.

And from my custom code, I’ve made a JSFiddle one that works fine (pre-scaled) is that I get the width and height from the window and the image, then get the overflowing values, then set the container to width = window width + overflow width * 2, height = window height + overflow height * 2 which it does work. But the problem is the .draggable() still uses the original size of the image resulting the image go past the containment

JSFiddle simulation

I’ve tried the stack overflow post (Asked on 2009) where they were creating an interface to allow a user to zoom in on an image and drag the zoomed version around within a clipping mask div.

From post

But when I applied the code to my very code, it gave me a reverse drag. Is there any way to make this possible?