OPEN SOURCE

{getBlock} $results={5} $label={OPEN SOURCE} $type={col-left} $color={#1abc9c}

PREMIUM

{getBlock} $results={5} $label={PREMIUM} $type={col-right} $color={#1abc9c}
© ‧ Interesting Homemade Projects. All rights reserved.

About Me...

Fletro Pro v6.1

Mauris lacus dolor, ultricies vel sodales ac, egestas vel eros.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Test link

Electron: Building for Mac, Windows and Linux

 



Electron: Building for Mac, Windows and Linux

Intro:

Electron is a framework that lets you build desktop applications using the same three technologies you already use on the web: HTML, CSS and JavaScript. It bundles Chromium (for rendering the interface) and Node.js (for the system-level work), so a single codebase can run as a native-feeling app on Windows, macOS and Linux. Visual Studio Code, Slack and Discord are all built this way.

Writing the app is the easy half. The half that usually trips people up is packaging: turning a folder of JavaScript files into an .exe installer, a .dmg disk image and an .AppImage or .deb package. That is what we are doing here. We will build a tiny demo app first, and then compile it for all three platforms with electron-builder.

Getting Started:

You only need Node.js (version 18 or newer) and npm. Check what you have:

bash
node -v
npm -v

Create the project folder and initialize it:

bash
mkdir electron-demo
cd electron-demo
npm init -y

Now install Electron and the packaging tool. Both are development dependencies — they are used to build the app, not shipped as part of it:

bash
npm install --save-dev electron electron-builder

This is the structure we are going to end up with:

electron-demo/ ├─ build/ │ ├─ icon.ico (Windows, 256×256) │ ├─ icon.icns (macOS) │ └─ icon.png (Linux, 512×512) ├─ renderer/ │ ├─ index.html │ ├─ styles.css │ └─ renderer.js ├─ main.js ├─ preload.js └─ package.json

The Demo App:

An Electron app has two kinds of processes. The main process is Node.js: it creates windows and talks to the operating system. The renderer process is the web page inside the window. They are isolated from each other, and a preload script is the bridge that exposes a controlled set of functions from one side to the other.

main.js

This creates the window and answers one message coming from the interface:

javascript
const { app, BrowserWindow, ipcMain } = require('electron');
const path = require('path');

function createWindow() {
  const win = new BrowserWindow({
    width: 720,
    height: 480,
    title: 'Electron Demo',
    webPreferences: {
      preload: path.join(__dirname, 'preload.js'),
      contextIsolation: true,
      nodeIntegration: false
    }
  });

  win.loadFile(path.join(__dirname, 'renderer', 'index.html'));
}

// Handler for the message sent by the renderer.
ipcMain.handle('get-info', () => {
  return {
    appVersion: app.getVersion(),
    electron: process.versions.electron,
    node: process.versions.node,
    chrome: process.versions.chrome,
    platform: process.platform,
    arch: process.arch
  };
});

app.whenReady().then(() => {
  createWindow();

  // On macOS, re-create the window when the dock icon is clicked.
  app.on('activate', () => {
    if (BrowserWindow.getAllWindows().length === 0) createWindow();
  });
});

// On Windows and Linux, closing every window quits the app.
app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') app.quit();
});

preload.js

Instead of giving the web page full access to Node, we expose exactly one function:

javascript
const { contextBridge, ipcRenderer } = require('electron');

contextBridge.exposeInMainWorld('api', {
  getInfo: () => ipcRenderer.invoke('get-info')
});

renderer/index.html

html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta http-equiv="Content-Security-Policy"
        content="default-src 'self'; script-src 'self'">
  <title>Electron Demo</title>
  <link rel="stylesheet" href="styles.css">
</head>
<body>
  <main>
    <h1>Hello from Electron</h1>
    <p id="version">Loading…</p>
    <p id="system"></p>
    <button id="refresh">Read system info</button>
  </main>
  <script src="renderer.js"></script>
</body>
</html>

renderer/styles.css

css
body {
  margin: 0;
  height: 100vh;
  display: grid;
  place-items: center;
  font-family: system-ui, "Segoe UI", Roboto, sans-serif;
  background: #f5f6f8;
  color: #22262b;
}
main { text-align: center; }
h1 { margin: 0 0 10px; font-size: 26px; }
p  { margin: 4px 0; color: #4b5563; }
button {
  margin-top: 16px;
  padding: 8px 18px;
  font-size: 14px;
  border: 1px solid #c9ced6;
  border-radius: 6px;
  background: #fff;
  cursor: pointer;
}
button:hover { background: #eef1f5; }

renderer/renderer.js

javascript
async function load() {
  const info = await window.api.getInfo();

  document.getElementById('version').textContent =
    'App version ' + info.appVersion;

  document.getElementById('system').textContent =
    info.platform + ' / ' + info.arch +
    ' • Electron ' + info.electron +
    ' • Node ' + info.node +
    ' • Chrome ' + info.chrome;
}

document.getElementById('refresh').addEventListener('click', load);
load();

package.json

Two things matter here: the scripts block (how we launch and build) and the build block (how electron-builder packages each platform):

json
{
  "name": "electron-demo",
  "version": "1.0.0",
  "description": "A simple cross-platform Electron demo",
  "author": "Luis A. Sierra",
  "license": "MIT",
  "main": "main.js",
  "scripts": {
    "start": "electron .",
    "dist:win": "electron-builder --win",
    "dist:mac": "electron-builder --mac",
    "dist:linux": "electron-builder --linux",
    "dist:all": "electron-builder -mwl"
  },
  "build": {
    "appId": "com.luissierra.electrondemo",
    "productName": "Electron Demo",
    "directories": {
      "output": "dist",
      "buildResources": "build"
    },
    "files": [
      "main.js",
      "preload.js",
      "renderer/**/*",
      "package.json"
    ],
    "win": {
      "target": ["nsis", "portable"],
      "icon": "build/icon.ico"
    },
    "nsis": {
      "oneClick": false,
      "allowToChangeInstallationDirectory": true,
      "createDesktopShortcut": true
    },
    "mac": {
      "target": [
        { "target": "dmg", "arch": ["x64", "arm64"] },
        { "target": "zip", "arch": ["x64", "arm64"] }
      ],
      "icon": "build/icon.icns",
      "category": "public.app-category.developer-tools"
    },
    "linux": {
      "target": ["AppImage", "deb"],
      "icon": "build/icon.png",
      "category": "Utility",
      "maintainer": "Luis A. Sierra <you@example.com>"
    }
  },
  "devDependencies": {
    "electron": "^33.2.0",
    "electron-builder": "^25.1.8"
  }
}

Run the app in development mode before packaging anything:

bash
npm start

Output:

The demo app running with npm start
Electron Demo

Hello from Electron

App version 1.0.0

win32 / x64 • Electron 33.2.0 • Node 20.18.0 • Chrome 130.0.6723.44

The Icons:

electron-builder will happily build without custom icons, but you will get the default Electron logo. Drop three files into build/ and it picks them up automatically:

FilePlatformRequirements
build/icon.icoWindowsMulti-size ICO, at least 256×256
build/icon.icnsmacOSICNS, from a 1024×1024 source
build/icon.pngLinuxPNG, 512×512 or 1024×1024

If you only have a PNG, the easiest path is to keep a 1024×1024 build/icon.png; electron-builder generates the missing formats for Linux and Windows from it. For macOS, providing the .icns yourself is the safer option.

Building for Windows:

Run this on a Windows machine:

bash
npm run dist:win

You end up with two artifacts inside dist/:

  • Electron Demo Setup 1.0.0.exe — an NSIS installer with a wizard, Start Menu entry and uninstaller.
  • Electron Demo 1.0.0.exe — the portable build, a single executable that runs with no installation.
bash
  • electron-builder  version=25.1.8
  • loaded configuration  file=package.json ("build" field)
  • packaging       platform=win32 arch=x64 electron=33.2.0
  • building        target=nsis file=dist\Electron Demo Setup 1.0.0.exe
  • building        target=portable file=dist\Electron Demo 1.0.0.exe

Want a 32-bit build too, or an MSI? Pass the architecture and target on the command line:

bash
npx electron-builder --win nsis --x64 --ia32
npx electron-builder --win msi

Building for macOS:

Run this on a Mac:

bash
npm run dist:mac

Because the mac block above lists both architectures, you get Intel and Apple Silicon versions:

  • Electron Demo-1.0.0.dmg — Intel (x64) disk image.
  • Electron Demo-1.0.0-arm64.dmg — Apple Silicon disk image.
  • .zip versions of both, which is the format auto-update uses on macOS.

You can also produce a single binary that runs natively on both chips:

bash
npx electron-builder --mac --universal
Heads-up on macOSAn unsigned app will be blocked by Gatekeeper on somebody else's Mac. For personal use that is fine — right-click the app and chooseOpen. To distribute it, you need an Apple Developer account, a Developer ID certificate, and notarization.

With a certificate installed and an app-specific password created, signing and notarizing is a matter of environment variables plus one flag:

bash
export APPLE_ID="you@example.com"
export APPLE_APP_SPECIFIC_PASSWORD="xxxx-xxxx-xxxx-xxxx"
export APPLE_TEAM_ID="ABCDE12345"

npm run dist:mac
json
"mac": {
  "notarize": true,
  "hardenedRuntime": true,
  "gatekeeperAssess": false,
  "entitlements": "build/entitlements.mac.plist"
}

Building for Linux:

Run this on a Linux machine (or inside WSL):

bash
npm run dist:linux

The result:

  • Electron Demo-1.0.0.AppImage — runs on virtually any distribution, no installation needed.
  • electron-demo_1.0.0_amd64.deb — package for Debian, Ubuntu and derivatives.

Make the AppImage executable and launch it:

bash
chmod +x "dist/Electron Demo-1.0.0.AppImage"
"./dist/Electron Demo-1.0.0.AppImage"

Other formats are just one more entry in the target list — rpm for Fedora and RHEL, snap for the Snap Store, tar.gz for a plain archive:

bash
npx electron-builder --linux AppImage deb rpm tar.gz

Cross-Compiling:

The command npm run dist:all (electron-builder -mwl) is real, but it only works from the right host. This is the part of the process worth memorizing:

You are onWindows targetmacOS targetLinux target
macOSYes (needs Wine)YesYes
LinuxYes (needs Wine)NoYes
WindowsYesNoPartially — use WSL or Docker

The short version: macOS builds require a Mac, because Apple's code-signing and DMG tooling does not exist anywhere else. Everything else can be arranged. On Linux you can build Windows and Linux artifacts inside the official Docker image without installing Wine yourself:

bash
docker run --rm -ti \
  -v ${PWD}:/project \
  -v ${PWD##*/}-node-modules:/project/node_modules \
  electronuserland/builder:wine \
  /bin/bash -c "npm install && npx electron-builder --win --linux"

Building All Three at Once:

The clean answer to the Mac problem is to let a build server do it. This GitHub Actions workflow runs the same build on three runners in parallel and uploads every artifact:

yaml
# .github/workflows/build.yml
name: Build desktop app

on:
  push:
    tags: ['v*']
  workflow_dispatch:

jobs:
  build:
    strategy:
      matrix:
        include:
          - os: windows-latest
            script: dist:win
          - os: macos-latest
            script: dist:mac
          - os: ubuntu-latest
            script: dist:linux

    runs-on: ${{ matrix.os }}

    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: npm

      - run: npm ci

      - run: npm run ${{ matrix.script }}

      - uses: actions/upload-artifact@v4
        with:
          name: build-${{ matrix.os }}
          path: dist/*.*

Push a tag such as v1.0.0 and a few minutes later you have installers for the three platforms sitting in the workflow's artifacts, all built from the same commit.

The dist Folder:

dist/ ├─ Electron Demo Setup 1.0.0.exe <- Windows installer ├─ Electron Demo 1.0.0.exe <- Windows portable ├─ Electron Demo-1.0.0.dmg <- macOS Intel ├─ Electron Demo-1.0.0-arm64.dmg <- macOS Apple Silicon ├─ Electron Demo-1.0.0.AppImage <- Linux universal ├─ electron-demo_1.0.0_amd64.deb <- Debian / Ubuntu ├─ latest.yml / latest-mac.yml <- auto-update metadata └─ win-unpacked/ mac/ linux-unpacked/ <- raw application folders
Expect a big downloadEvery Electron app ships its own copy of Chromium, so even this demo lands somewhere around 70–100 MB per installer. That is normal, and there is no way around it — it is the price of the framework.

Common Problems:

  • A blank white window. Almost always a wrong path in win.loadFile(). Always build the path with path.join(__dirname, ...), never a relative string.
  • Works with npm start, fails when packaged. A file is missing from the files array in the build config. Anything the app loads at runtime has to be listed there.
  • window.api is undefined. The preload path is wrong, or contextIsolation was turned off.
  • “Cannot find module” after packaging. The package was installed with --save-dev but the app needs it at runtime. Move it to dependencies.
  • The build hangs on the first run. electron-builder is downloading the Electron binaries and the NSIS/Wine helpers into its cache. Let it finish; later builds are much faster.

Files:

The complete demo — main.js, preload.js, the renderer folder and the full package.json — is available in the repository:

https://gitlab.com/luisalbertosierraalcantara/electron-demo

CodeIgniter 4 SQL-Server Simple CRUD Step-by-Step Tutorial

CodeIgniter 4 SQL-Server Simple CRUD Step-by-Step Tutorial

CodeIgniter is an open-source web framework that is used for rapid web development. CodeIgniter follows the MVC (Model-View-Controller) architectural pattern. It is noted for its speed compared to other PHP web frameworks.


Application Flow Chart

  1. The index.php serves as the front controller, initializing the base resources needed to run CodeIgniter.
  2. The Router examines the HTTP request to determine what should be done with it.
  3. If a cache file exists, it is sent directly to the browser, bypassing the normal system execution.
  4. Security. Before the application controller is loaded, the HTTP request and any user submitted data is filtered for security.
  5. The Controller loads the model, core libraries, helpers, and any other resources needed to process the specific request.
  6. The finalized View is rendered then sent to the web browser to be seen. If caching is enabled, the view is cached first so that on subsequent requests it can be served.

CRUD is an acronym for CREATE, READ, UPDATE, DELETE. The four basic functions in any type of programming. 

CRUD typically refers to operations performed in a database.
  • Create -Generate new record/s.
  • Read – Reads or retrieve record/s.
  • Update – Modify record/s.
  • Delete – Destroy or remove record/s.
Before proceeding on this tutorial, you must have an environment already setup to run and install CodeIgniter 4. 


Set Database Configuration

Run this SQL query to create the crud_projects database 

✂️ Copy and 📋 Paste 👇 


CREATE DATABASE crud_projects;


Run this SQL query to create the crud_data 
table:

✂️ Copy and 📋 Paste 👇 


CREATE TABLE crud_data (
    id INT IDENTITY(1,1) PRIMARY KEY,
    name NVARCHAR(255) NOT NULL,
    phone NVARCHAR(15) NOT NULL,
    address NVARCHAR(255) NOT NULL,
    created_date DATETIME NULL DEFAULT GETDATE(),
    updated_date DATETIME NULL DEFAULT NULL
);


Install PHP SQLSRV Driver:

✅ How to Install Microsoft Drivers for PHP and SQL-SERVER

⚠️ Important Note:

⚙️ Don't forget that before continuing, SQL-SERVER must have network access enabled.

Open the app folder and configure your database on this file “Config/database.php“.


✂️ Copy and 📋 Paste 👇 

public array $default = [
    'DSN'        => '',
    'hostname'   => 'localhost', //e.g., 'localhost' or '192.168.1.100'
    'username'   => 'your_sql_server_username',
    'password'   => 'your_sql_server_password',
    'database'   => 'crud_projects',
    'schema'     => 'dbo',
    'DBDriver'   => 'SQLSRV',   //Specify the SQLSRV driver
    'DBPrefix'   => '',
    'pConnect'   => false,
    'DBDebug'    => true,
    'charset'    => 'utf8',
    'swapPre'    => '',
    'encrypt'    => false,
    'failover'   => [],
    'port'       => 1433,       //Default SQL-Server port, modify if yours is different
    'dateFormat' => [
        'date'     => 'Y-m-d',
        'datetime' => 'Y-m-d H:i:s',
        'time'     => 'H:i:s',
    ],
];

Update Config/App.php

Open the file Config/App.php and find and update the base_url value.

Remove "index.php" in Config/App.php

Update Register Routes

And now we will register the routes for our CRUD app.

Callable Syntax (Example):
$routes->get('/', [\App\Controllers\Home::class, 'index']);
Open the Config/routes.php file and register these route:

✂️ Copy and 📋 Paste 👇 

 
<?php

use CodeIgniter\Router\RouteCollection;

/**
 * @var RouteCollection $routes
 */

$routes->get('/', 'Crud::index');
$routes->get('crud', 'Crud::index');
$routes->get('crud/create', 'Crud::create_page');
$routes->post('crud/save', 'Crud::save_record');
$routes->get('crud/show_page/(:num)', 'Crud::show_page/$1');
$routes->get('crud/edit/(:num)', 'Crud::edit_page/$1');
$routes->put('crud/update/(:num)', 'Crud::update_record/$1');
$routes->post('crud/update/(:num)', 'Crud::update_record/$1');
$routes->get('crud/delete/(:num)', 'Crud::delete_record/$1');
$routes->delete('crud/delete/(:num)', 'Crud::delete_record/$1');

Create Controller

Go to this path “application/controllers/” and create a controller named Crud.php. This will handle all our users actions. 


The controller will have these following methods
  • index()
  • show_page($id)
  • create_page()
  • save_record()
  • edit_page($id)
  • update_record($id)
  • delete_record($id)
After creating the controller, insert the codes below:

application/controllers/Crud.php

✂️ Copy and 📋 Paste 👇 


<?php
/*-----------------------------------------------------------------------------------------------------
  ----------------------- This PHP Script was created by Luis A. Sierra -------------------------------
  -----------------------------------------------------------------------------------------------------*/
namespace App\Controllers;

use App\Models\CrudModel;
use CodeIgniter\Controller;

class Crud extends Controller
{
    protected $crud;
    protected $session;
    protected $validation;

    public function __construct()
    {
        $this->crud = new CrudModel();
        $this->session = session();
        $this->validation = \Config\Services::validation();
    }

    public function index()
    {
        $data = [
            'cruds' => $this->crud->getAll(),
            'title' => 'CodeIgniter 4 Crud for SQL-SERVER',
        ];
        return view('layout/header_view')
             . view('crud/index', $data)
             . view('layout/footer_view');
    }

    public function show_page($id)
    {
        $data = [
            'crud' => $this->crud->getById($id),
            'title' => 'Show Crud',
        ];
        return view('layout/header_view')
             . view('crud/show_view', $data)
             . view('layout/footer_view');
    }

    public function create_page()
    {
        $data['title'] = 'Create Crud';
        return view('layout/header_view')
             . view('crud/create_view', $data)
             . view('layout/footer_view');
    }

    public function save_record()
    {
        $rules = [
            'name' => 'required',
            'phone' => 'required',
            'address' => 'required',
        ];

        if (!$this->validate($rules)) {
            $this->session->setFlashdata('errors', $this->validator->listErrors());
            return redirect()->to(base_url('crud/create'));
        }

        $this->crud->saveRecord([
            'name' => $this->request->getPost('name'),
            'phone' => $this->request->getPost('phone'),
            'address' => $this->request->getPost('address'),
        ]);

        $this->session->setFlashdata('success', 'Saved Successfully!');
        return redirect()->to(base_url('crud'));
    }

    public function edit_page($id)
    {
        $data = [
            'crud' => $this->crud->getById($id),
            'title' => 'Edit Crud',
        ];
        return view('layout/header_view')
             . view('crud/edit_view', $data)
             . view('layout/footer_view');
    }

    public function update_record($id)
    {
        $rules = [
            'name' => 'required',
            'phone' => 'required',
            'address' => 'required',
        ];

        if (!$this->validate($rules)) {
            $this->session->setFlashdata('errors', $this->validator->listErrors());
            return redirect()->to(base_url("crud/edit/$id"));
        }

        $this->crud->updateRecord($id, [
            'name' => $this->request->getPost('name'),
            'phone' => $this->request->getPost('phone'),
            'address' => $this->request->getPost('address'),
        ]);

        $this->session->setFlashdata('success', 'Updated Successfully!');
        return redirect()->to(base_url('crud'));
    }

    public function delete_record($id)
    {
        $this->crud->deleteRecord($id);
        $this->session->setFlashdata('success', 'Deleted Successfully!');
        return redirect()->to(base_url('crud'));
    }
}

Create Model

Go to this path “application/models/” and create a model named CrudModel.php. This will handle all our query to the database. The model will have this following methods.
  • getAll()
  • saveRecord()
  • getById($id)
  • updateRecord($id)
  • deleteRecord($id)
After creating the model, insert the code below:


application/models/CrudModel.php

✂️ Copy and 📋 Paste 👇 


<?php
/*-----------------------------------------------------------------------------------------------------
  ----------------------- This PHP Script was created by Luis A. Sierra -------------------------------
  -----------------------------------------------------------------------------------------------------*/
namespace App\Models;

use CodeIgniter\Model;

class CrudModel extends Model
{
    protected $table = 'crud_data';       // Database table name
    protected $primaryKey = 'id';         // Primary key column
    protected $allowedFields = ['name', 'phone', 'address']; // Editable fields
    protected $useTimestamps = false;     // Set true if you use created_at / updated_at fields
    protected $returnType = 'object';     // Return results as objects

    /*
        Get all records
    */
    public function getAll()
    {
        return $this->findAll();
    }

    /*
        Get a specific record by ID
    */
    public function getById($id)
    {
        return $this->find($id);
    }

    /*
        Insert new record
    */
    public function saveRecord(array $data)
    {
        return $this->insert($data);
    }

    /*
        Update record by ID
    */
    public function updateRecord($id, array $data)
    {
        return $this->update($id, $data);
    }

    /*
        Delete record by ID
    */
    public function deleteRecord($id)
    {
        return $this->delete($id);
    }
}

Create View Files


We will now create the view files. The Views are the codes that what the user see and the code that the user can interact. We will create all these files:
  • layout/header_view.php
  • layout/footer_view.php
  • crud/index_view.php
  • crud/create_view.php
  • crud/edit_view.php
  • crud/show_view.php
application/views/layout/header_view.php

✂️ Copy and 📋 Paste 👇 


<!DOCTYPE html>
<html>
<head>
    <title>CodeIgniter CRUD</title>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.4.0/js/bootstrap.min.js" rel="stylesheet">
    <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
</head>
<body>
    <div class="container">

application/views/layout/footer_view.php

✂️ Copy and 📋 Paste 👇 


    </div>
    <center>CodeIgniter CRUD Created by <b>Luis A. Sierra</b></center>
    </body>
</html>


application/views/crud/index.php

✂️ Copy and 📋 Paste 👇 


<h2 class="text-center mt-5 mb-3"><?php echo $title; ?></h2>
<div class="card">
    <div class="card-header">
        <a class="btn btn-outline-primary" href="<?php echo base_url('crud/create/');?>">
            Create New Record
        </a>
    </div>
    <div class="card-body">
        <?php if (session()->getFlashdata('success')) {?>
            <div class="alert alert-success">
                <?php echo session()->getFlashdata('success'); ?>
            </div>
        <?php } ?>
 
        <table class="table table-bordered">
            <tr>
                <th>Name</th>
                <th>Phone</th>
                <th>Address</th>
                <th width="240px">Action</th>
            </tr>
 
            <?php foreach ($cruds as $crud) { ?>      
            <tr>
                <td><?php echo $crud->name; ?></td>
                <td><?php echo $crud->phone; ?></td>  
                <td><?php echo $crud->address; ?></td>                  
                <td>
                    <a
                        class="btn btn-outline-info"
                        href="<?php echo base_url('crud/show_page/'. $crud->id) ?>">
                        Show
                    </a>
                    <a
                        class="btn btn-outline-success"
                        href="<?php echo base_url('crud/edit/'.$crud->id) ?>">
                        Edit
                    </a>
                    <a
                        class="btn btn-outline-danger"
                        href="<?php echo base_url('crud/delete/'.$crud->id) ?>">
                        Delete
                    </a>
                </td>    
            </tr>
            <?php } ?>
        </table>
    </div>
</div>

application/views/crud/create_view.php

✂️ Copy and 📋 Paste 👇 


<h2 class="text-center mt-5 mb-3"><?php echo $title; ?></h2>
<div class="card">
    <div class="card-header">
        <a class="btn btn-outline-secondary" href="<?php echo base_url('crud/');?>">
            Back
        </a>
    </div>
    <div class="card-body">
        <?php if (session()->getFlashdata('errors')) {?>
            <div class="alert alert-danger">
                <?php echo session()->getFlashdata('errors'); ?>
            </div>
        <?php } ?>

        <form method="post" action="<?php echo base_url('crud/save'); ?>">
            <div class="form-group">
                <label for="name">Name:</label>
                <input type="text" class="form-control" id="name" name="name" placeholder="Enter name" value="<?php echo old('name'); ?>">
            </div>
            <div class="form-group">
                <label for="phone">Phone:</label>
                <input type="text" class="form-control" id="phone" name="phone" placeholder="Enter phone" value="<?php echo old('phone'); ?>">
            </div>
            <div class="form-group">
                <label for="address">Address:</label>
                <textarea class="form-control" id="address" name="address" placeholder="Enter address"><?php echo old('address'); ?></textarea>
            </div>
            <button type="submit" class="btn btn-success">Save</button>
        </form>
    </div>
</div>

application/views/crud/edit_view.php

✂️ Copy and 📋 Paste 👇 


<h2 class="text-center mt-5 mb-3"><?php echo $title; ?></h2>
<div class="card">
    <div class="card-header">
        <a class="btn btn-outline-secondary" href="<?php echo base_url('crud/');?>">
            Back
        </a>
    </div>
    <div class="card-body">
        <?php if (session()->getFlashdata('errors')) {?>
            <div class="alert alert-danger">
                <?php echo session()->getFlashdata('errors'); ?>
            </div>
        <?php } ?>

        <?php if (!empty($crud)) { ?>
            <form method="post" action="<?php echo base_url('crud/update/'.$crud->id); ?>">
                <?= csrf_field() ?>
                <input type="hidden" name="_method" value="PUT">
                <div class="form-group">
                    <label for="name">Name:</label>
                    <input type="text" class="form-control" id="name" name="name" placeholder="Enter name" value="<?php echo old('name', $crud->name); ?>">
                </div>
                <div class="form-group">
                    <label for="phone">Phone:</label>
                    <input type="text" class="form-control" id="phone" name="phone" placeholder="Enter phone" value="<?php echo old('phone', $crud->phone); ?>">
                </div>
                <div class="form-group">
                    <label for="address">Address:</label>
                    <textarea class="form-control" id="address" name="address" placeholder="Enter address"><?php echo old('address', $crud->address); ?></textarea>
                </div>
                <button type="submit" class="btn btn-success">Update</button>
            </form>
        <?php } else { ?>
            <p class="alert alert-warning">Record not found.</p>
        <?php } ?>
    </div>
</div>

application/views/crud/show_view.php

✂️ Copy and 📋 Paste 👇 


<h2 class="text-center mt-5 mb-3"><?php echo $title; ?></h2>
<div class="card">
    <div class="card-header">
        <a class="btn btn-outline-secondary" href="<?php echo base_url('crud/');?>">
            Back
        </a>
    </div>
    <div class="card-body">
        <?php if (!empty($crud)) { ?>
            <div class="form-group">
                <strong>Name:</strong>
                <p><?php echo $crud->name; ?></p>
            </div>
            <div class="form-group">
                <strong>Phone:</strong>
                <p><?php echo $crud->phone; ?></p>
            </div>
            <div class="form-group">
                <strong>Address:</strong>
                <p><?php echo $crud->address; ?></p>
            </div>
        <?php } else { ?>
            <p class="alert alert-warning">Record not found.</p>
        <?php } ?>
    </div>
</div>

Finally all the components are done.

Now we can test our CodeIgniter 4 Simple CRUD App by browsing this URL:

http://localhost:8080/crud

📷 Screenshots:

CodeIgniter 4 Simple CRUD App:









Congratulations 😎👏

Electron: Building for Mac, Windows and Linux

 



Electron: Building for Mac, Windows and Linux

Intro:

Electron is a framework that lets you build desktop applications using the same three technologies you already use on the web: HTML, CSS and JavaScript. It bundles Chromium (for rendering the interface) and Node.js (for the system-level work), so a single codebase can run as a native-feeling app on Windows, macOS and Linux. Visual Studio Code, Slack and Discord are all built this way.

Writing the app is the easy half. The half that usually trips people up is packaging: turning a folder of JavaScript files into an .exe installer, a .dmg disk image and an .AppImage or .deb package. That is what we are doing here. We will build a tiny demo app first, and then compile it for all three platforms with electron-builder.

Getting Started:

You only need Node.js (version 18 or newer) and npm. Check what you have:

bash
node -v
npm -v

Create the project folder and initialize it:

bash
mkdir electron-demo
cd electron-demo
npm init -y

Now install Electron and the packaging tool. Both are development dependencies — they are used to build the app, not shipped as part of it:

bash
npm install --save-dev electron electron-builder

This is the structure we are going to end up with:

electron-demo/ ├─ build/ │ ├─ icon.ico (Windows, 256×256) │ ├─ icon.icns (macOS) │ └─ icon.png (Linux, 512×512) ├─ renderer/ │ ├─ index.html │ ├─ styles.css │ └─ renderer.js ├─ main.js ├─ preload.js └─ package.json

The Demo App:

An Electron app has two kinds of processes. The main process is Node.js: it creates windows and talks to the operating system. The renderer process is the web page inside the window. They are isolated from each other, and a preload script is the bridge that exposes a controlled set of functions from one side to the other.

main.js

This creates the window and answers one message coming from the interface:

javascript
const { app, BrowserWindow, ipcMain } = require('electron');
const path = require('path');

function createWindow() {
  const win = new BrowserWindow({
    width: 720,
    height: 480,
    title: 'Electron Demo',
    webPreferences: {
      preload: path.join(__dirname, 'preload.js'),
      contextIsolation: true,
      nodeIntegration: false
    }
  });

  win.loadFile(path.join(__dirname, 'renderer', 'index.html'));
}

// Handler for the message sent by the renderer.
ipcMain.handle('get-info', () => {
  return {
    appVersion: app.getVersion(),
    electron: process.versions.electron,
    node: process.versions.node,
    chrome: process.versions.chrome,
    platform: process.platform,
    arch: process.arch
  };
});

app.whenReady().then(() => {
  createWindow();

  // On macOS, re-create the window when the dock icon is clicked.
  app.on('activate', () => {
    if (BrowserWindow.getAllWindows().length === 0) createWindow();
  });
});

// On Windows and Linux, closing every window quits the app.
app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') app.quit();
});

preload.js

Instead of giving the web page full access to Node, we expose exactly one function:

javascript
const { contextBridge, ipcRenderer } = require('electron');

contextBridge.exposeInMainWorld('api', {
  getInfo: () => ipcRenderer.invoke('get-info')
});

renderer/index.html

html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta http-equiv="Content-Security-Policy"
        content="default-src 'self'; script-src 'self'">
  <title>Electron Demo</title>
  <link rel="stylesheet" href="styles.css">
</head>
<body>
  <main>
    <h1>Hello from Electron</h1>
    <p id="version">Loading…</p>
    <p id="system"></p>
    <button id="refresh">Read system info</button>
  </main>
  <script src="renderer.js"></script>
</body>
</html>

renderer/styles.css

css
body {
  margin: 0;
  height: 100vh;
  display: grid;
  place-items: center;
  font-family: system-ui, "Segoe UI", Roboto, sans-serif;
  background: #f5f6f8;
  color: #22262b;
}
main { text-align: center; }
h1 { margin: 0 0 10px; font-size: 26px; }
p  { margin: 4px 0; color: #4b5563; }
button {
  margin-top: 16px;
  padding: 8px 18px;
  font-size: 14px;
  border: 1px solid #c9ced6;
  border-radius: 6px;
  background: #fff;
  cursor: pointer;
}
button:hover { background: #eef1f5; }

renderer/renderer.js

javascript
async function load() {
  const info = await window.api.getInfo();

  document.getElementById('version').textContent =
    'App version ' + info.appVersion;

  document.getElementById('system').textContent =
    info.platform + ' / ' + info.arch +
    ' • Electron ' + info.electron +
    ' • Node ' + info.node +
    ' • Chrome ' + info.chrome;
}

document.getElementById('refresh').addEventListener('click', load);
load();

package.json

Two things matter here: the scripts block (how we launch and build) and the build block (how electron-builder packages each platform):

json
{
  "name": "electron-demo",
  "version": "1.0.0",
  "description": "A simple cross-platform Electron demo",
  "author": "Luis A. Sierra",
  "license": "MIT",
  "main": "main.js",
  "scripts": {
    "start": "electron .",
    "dist:win": "electron-builder --win",
    "dist:mac": "electron-builder --mac",
    "dist:linux": "electron-builder --linux",
    "dist:all": "electron-builder -mwl"
  },
  "build": {
    "appId": "com.luissierra.electrondemo",
    "productName": "Electron Demo",
    "directories": {
      "output": "dist",
      "buildResources": "build"
    },
    "files": [
      "main.js",
      "preload.js",
      "renderer/**/*",
      "package.json"
    ],
    "win": {
      "target": ["nsis", "portable"],
      "icon": "build/icon.ico"
    },
    "nsis": {
      "oneClick": false,
      "allowToChangeInstallationDirectory": true,
      "createDesktopShortcut": true
    },
    "mac": {
      "target": [
        { "target": "dmg", "arch": ["x64", "arm64"] },
        { "target": "zip", "arch": ["x64", "arm64"] }
      ],
      "icon": "build/icon.icns",
      "category": "public.app-category.developer-tools"
    },
    "linux": {
      "target": ["AppImage", "deb"],
      "icon": "build/icon.png",
      "category": "Utility",
      "maintainer": "Luis A. Sierra <you@example.com>"
    }
  },
  "devDependencies": {
    "electron": "^33.2.0",
    "electron-builder": "^25.1.8"
  }
}

Run the app in development mode before packaging anything:

bash
npm start

Output:

The demo app running with npm start
Electron Demo

Hello from Electron

App version 1.0.0

win32 / x64 • Electron 33.2.0 • Node 20.18.0 • Chrome 130.0.6723.44

The Icons:

electron-builder will happily build without custom icons, but you will get the default Electron logo. Drop three files into build/ and it picks them up automatically:

FilePlatformRequirements
build/icon.icoWindowsMulti-size ICO, at least 256×256
build/icon.icnsmacOSICNS, from a 1024×1024 source
build/icon.pngLinuxPNG, 512×512 or 1024×1024

If you only have a PNG, the easiest path is to keep a 1024×1024 build/icon.png; electron-builder generates the missing formats for Linux and Windows from it. For macOS, providing the .icns yourself is the safer option.

Building for Windows:

Run this on a Windows machine:

bash
npm run dist:win

You end up with two artifacts inside dist/:

  • Electron Demo Setup 1.0.0.exe — an NSIS installer with a wizard, Start Menu entry and uninstaller.
  • Electron Demo 1.0.0.exe — the portable build, a single executable that runs with no installation.
bash
  • electron-builder  version=25.1.8
  • loaded configuration  file=package.json ("build" field)
  • packaging       platform=win32 arch=x64 electron=33.2.0
  • building        target=nsis file=dist\Electron Demo Setup 1.0.0.exe
  • building        target=portable file=dist\Electron Demo 1.0.0.exe

Want a 32-bit build too, or an MSI? Pass the architecture and target on the command line:

bash
npx electron-builder --win nsis --x64 --ia32
npx electron-builder --win msi

Building for macOS:

Run this on a Mac:

bash
npm run dist:mac

Because the mac block above lists both architectures, you get Intel and Apple Silicon versions:

  • Electron Demo-1.0.0.dmg — Intel (x64) disk image.
  • Electron Demo-1.0.0-arm64.dmg — Apple Silicon disk image.
  • .zip versions of both, which is the format auto-update uses on macOS.

You can also produce a single binary that runs natively on both chips:

bash
npx electron-builder --mac --universal
Heads-up on macOSAn unsigned app will be blocked by Gatekeeper on somebody else's Mac. For personal use that is fine — right-click the app and chooseOpen. To distribute it, you need an Apple Developer account, a Developer ID certificate, and notarization.

With a certificate installed and an app-specific password created, signing and notarizing is a matter of environment variables plus one flag:

bash
export APPLE_ID="you@example.com"
export APPLE_APP_SPECIFIC_PASSWORD="xxxx-xxxx-xxxx-xxxx"
export APPLE_TEAM_ID="ABCDE12345"

npm run dist:mac
json
"mac": {
  "notarize": true,
  "hardenedRuntime": true,
  "gatekeeperAssess": false,
  "entitlements": "build/entitlements.mac.plist"
}

Building for Linux:

Run this on a Linux machine (or inside WSL):

bash
npm run dist:linux

The result:

  • Electron Demo-1.0.0.AppImage — runs on virtually any distribution, no installation needed.
  • electron-demo_1.0.0_amd64.deb — package for Debian, Ubuntu and derivatives.

Make the AppImage executable and launch it:

bash
chmod +x "dist/Electron Demo-1.0.0.AppImage"
"./dist/Electron Demo-1.0.0.AppImage"

Other formats are just one more entry in the target list — rpm for Fedora and RHEL, snap for the Snap Store, tar.gz for a plain archive:

bash
npx electron-builder --linux AppImage deb rpm tar.gz

Cross-Compiling:

The command npm run dist:all (electron-builder -mwl) is real, but it only works from the right host. This is the part of the process worth memorizing:

You are onWindows targetmacOS targetLinux target
macOSYes (needs Wine)YesYes
LinuxYes (needs Wine)NoYes
WindowsYesNoPartially — use WSL or Docker

The short version: macOS builds require a Mac, because Apple's code-signing and DMG tooling does not exist anywhere else. Everything else can be arranged. On Linux you can build Windows and Linux artifacts inside the official Docker image without installing Wine yourself:

bash
docker run --rm -ti \
  -v ${PWD}:/project \
  -v ${PWD##*/}-node-modules:/project/node_modules \
  electronuserland/builder:wine \
  /bin/bash -c "npm install && npx electron-builder --win --linux"

Building All Three at Once:

The clean answer to the Mac problem is to let a build server do it. This GitHub Actions workflow runs the same build on three runners in parallel and uploads every artifact:

yaml
# .github/workflows/build.yml
name: Build desktop app

on:
  push:
    tags: ['v*']
  workflow_dispatch:

jobs:
  build:
    strategy:
      matrix:
        include:
          - os: windows-latest
            script: dist:win
          - os: macos-latest
            script: dist:mac
          - os: ubuntu-latest
            script: dist:linux

    runs-on: ${{ matrix.os }}

    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: npm

      - run: npm ci

      - run: npm run ${{ matrix.script }}

      - uses: actions/upload-artifact@v4
        with:
          name: build-${{ matrix.os }}
          path: dist/*.*

Push a tag such as v1.0.0 and a few minutes later you have installers for the three platforms sitting in the workflow's artifacts, all built from the same commit.

The dist Folder:

dist/ ├─ Electron Demo Setup 1.0.0.exe <- Windows installer ├─ Electron Demo 1.0.0.exe <- Windows portable ├─ Electron Demo-1.0.0.dmg <- macOS Intel ├─ Electron Demo-1.0.0-arm64.dmg <- macOS Apple Silicon ├─ Electron Demo-1.0.0.AppImage <- Linux universal ├─ electron-demo_1.0.0_amd64.deb <- Debian / Ubuntu ├─ latest.yml / latest-mac.yml <- auto-update metadata └─ win-unpacked/ mac/ linux-unpacked/ <- raw application folders
Expect a big downloadEvery Electron app ships its own copy of Chromium, so even this demo lands somewhere around 70–100 MB per installer. That is normal, and there is no way around it — it is the price of the framework.

Common Problems:

  • A blank white window. Almost always a wrong path in win.loadFile(). Always build the path with path.join(__dirname, ...), never a relative string.
  • Works with npm start, fails when packaged. A file is missing from the files array in the build config. Anything the app loads at runtime has to be listed there.
  • window.api is undefined. The preload path is wrong, or contextIsolation was turned off.
  • “Cannot find module” after packaging. The package was installed with --save-dev but the app needs it at runtime. Move it to dependencies.
  • The build hangs on the first run. electron-builder is downloading the Electron binaries and the NSIS/Wine helpers into its cache. Let it finish; later builds are much faster.

Files:

The complete demo — main.js, preload.js, the renderer folder and the full package.json — is available in the repository:

https://gitlab.com/luisalbertosierraalcantara/electron-demo

CodeIgniter 4 SQL-Server Simple CRUD Step-by-Step Tutorial

CodeIgniter 4 SQL-Server Simple CRUD Step-by-Step Tutorial

CodeIgniter is an open-source web framework that is used for rapid web development. CodeIgniter follows the MVC (Model-View-Controller) architectural pattern. It is noted for its speed compared to other PHP web frameworks.


Application Flow Chart

  1. The index.php serves as the front controller, initializing the base resources needed to run CodeIgniter.
  2. The Router examines the HTTP request to determine what should be done with it.
  3. If a cache file exists, it is sent directly to the browser, bypassing the normal system execution.
  4. Security. Before the application controller is loaded, the HTTP request and any user submitted data is filtered for security.
  5. The Controller loads the model, core libraries, helpers, and any other resources needed to process the specific request.
  6. The finalized View is rendered then sent to the web browser to be seen. If caching is enabled, the view is cached first so that on subsequent requests it can be served.

CRUD is an acronym for CREATE, READ, UPDATE, DELETE. The four basic functions in any type of programming. 

CRUD typically refers to operations performed in a database.
  • Create -Generate new record/s.
  • Read – Reads or retrieve record/s.
  • Update – Modify record/s.
  • Delete – Destroy or remove record/s.
Before proceeding on this tutorial, you must have an environment already setup to run and install CodeIgniter 4. 


Set Database Configuration

Run this SQL query to create the crud_projects database 

✂️ Copy and 📋 Paste 👇 


CREATE DATABASE crud_projects;


Run this SQL query to create the crud_data 
table:

✂️ Copy and 📋 Paste 👇 


CREATE TABLE crud_data (
    id INT IDENTITY(1,1) PRIMARY KEY,
    name NVARCHAR(255) NOT NULL,
    phone NVARCHAR(15) NOT NULL,
    address NVARCHAR(255) NOT NULL,
    created_date DATETIME NULL DEFAULT GETDATE(),
    updated_date DATETIME NULL DEFAULT NULL
);


Install PHP SQLSRV Driver:

✅ How to Install Microsoft Drivers for PHP and SQL-SERVER

⚠️ Important Note:

⚙️ Don't forget that before continuing, SQL-SERVER must have network access enabled.

Open the app folder and configure your database on this file “Config/database.php“.


✂️ Copy and 📋 Paste 👇 

public array $default = [
    'DSN'        => '',
    'hostname'   => 'localhost', //e.g., 'localhost' or '192.168.1.100'
    'username'   => 'your_sql_server_username',
    'password'   => 'your_sql_server_password',
    'database'   => 'crud_projects',
    'schema'     => 'dbo',
    'DBDriver'   => 'SQLSRV',   //Specify the SQLSRV driver
    'DBPrefix'   => '',
    'pConnect'   => false,
    'DBDebug'    => true,
    'charset'    => 'utf8',
    'swapPre'    => '',
    'encrypt'    => false,
    'failover'   => [],
    'port'       => 1433,       //Default SQL-Server port, modify if yours is different
    'dateFormat' => [
        'date'     => 'Y-m-d',
        'datetime' => 'Y-m-d H:i:s',
        'time'     => 'H:i:s',
    ],
];

Update Config/App.php

Open the file Config/App.php and find and update the base_url value.

Remove "index.php" in Config/App.php

Update Register Routes

And now we will register the routes for our CRUD app.

Callable Syntax (Example):
$routes->get('/', [\App\Controllers\Home::class, 'index']);
Open the Config/routes.php file and register these route:

✂️ Copy and 📋 Paste 👇 

 
<?php

use CodeIgniter\Router\RouteCollection;

/**
 * @var RouteCollection $routes
 */

$routes->get('/', 'Crud::index');
$routes->get('crud', 'Crud::index');
$routes->get('crud/create', 'Crud::create_page');
$routes->post('crud/save', 'Crud::save_record');
$routes->get('crud/show_page/(:num)', 'Crud::show_page/$1');
$routes->get('crud/edit/(:num)', 'Crud::edit_page/$1');
$routes->put('crud/update/(:num)', 'Crud::update_record/$1');
$routes->post('crud/update/(:num)', 'Crud::update_record/$1');
$routes->get('crud/delete/(:num)', 'Crud::delete_record/$1');
$routes->delete('crud/delete/(:num)', 'Crud::delete_record/$1');

Create Controller

Go to this path “application/controllers/” and create a controller named Crud.php. This will handle all our users actions. 


The controller will have these following methods
  • index()
  • show_page($id)
  • create_page()
  • save_record()
  • edit_page($id)
  • update_record($id)
  • delete_record($id)
After creating the controller, insert the codes below:

application/controllers/Crud.php

✂️ Copy and 📋 Paste 👇 


<?php
/*-----------------------------------------------------------------------------------------------------
  ----------------------- This PHP Script was created by Luis A. Sierra -------------------------------
  -----------------------------------------------------------------------------------------------------*/
namespace App\Controllers;

use App\Models\CrudModel;
use CodeIgniter\Controller;

class Crud extends Controller
{
    protected $crud;
    protected $session;
    protected $validation;

    public function __construct()
    {
        $this->crud = new CrudModel();
        $this->session = session();
        $this->validation = \Config\Services::validation();
    }

    public function index()
    {
        $data = [
            'cruds' => $this->crud->getAll(),
            'title' => 'CodeIgniter 4 Crud for SQL-SERVER',
        ];
        return view('layout/header_view')
             . view('crud/index', $data)
             . view('layout/footer_view');
    }

    public function show_page($id)
    {
        $data = [
            'crud' => $this->crud->getById($id),
            'title' => 'Show Crud',
        ];
        return view('layout/header_view')
             . view('crud/show_view', $data)
             . view('layout/footer_view');
    }

    public function create_page()
    {
        $data['title'] = 'Create Crud';
        return view('layout/header_view')
             . view('crud/create_view', $data)
             . view('layout/footer_view');
    }

    public function save_record()
    {
        $rules = [
            'name' => 'required',
            'phone' => 'required',
            'address' => 'required',
        ];

        if (!$this->validate($rules)) {
            $this->session->setFlashdata('errors', $this->validator->listErrors());
            return redirect()->to(base_url('crud/create'));
        }

        $this->crud->saveRecord([
            'name' => $this->request->getPost('name'),
            'phone' => $this->request->getPost('phone'),
            'address' => $this->request->getPost('address'),
        ]);

        $this->session->setFlashdata('success', 'Saved Successfully!');
        return redirect()->to(base_url('crud'));
    }

    public function edit_page($id)
    {
        $data = [
            'crud' => $this->crud->getById($id),
            'title' => 'Edit Crud',
        ];
        return view('layout/header_view')
             . view('crud/edit_view', $data)
             . view('layout/footer_view');
    }

    public function update_record($id)
    {
        $rules = [
            'name' => 'required',
            'phone' => 'required',
            'address' => 'required',
        ];

        if (!$this->validate($rules)) {
            $this->session->setFlashdata('errors', $this->validator->listErrors());
            return redirect()->to(base_url("crud/edit/$id"));
        }

        $this->crud->updateRecord($id, [
            'name' => $this->request->getPost('name'),
            'phone' => $this->request->getPost('phone'),
            'address' => $this->request->getPost('address'),
        ]);

        $this->session->setFlashdata('success', 'Updated Successfully!');
        return redirect()->to(base_url('crud'));
    }

    public function delete_record($id)
    {
        $this->crud->deleteRecord($id);
        $this->session->setFlashdata('success', 'Deleted Successfully!');
        return redirect()->to(base_url('crud'));
    }
}

Create Model

Go to this path “application/models/” and create a model named CrudModel.php. This will handle all our query to the database. The model will have this following methods.
  • getAll()
  • saveRecord()
  • getById($id)
  • updateRecord($id)
  • deleteRecord($id)
After creating the model, insert the code below:


application/models/CrudModel.php

✂️ Copy and 📋 Paste 👇 


<?php
/*-----------------------------------------------------------------------------------------------------
  ----------------------- This PHP Script was created by Luis A. Sierra -------------------------------
  -----------------------------------------------------------------------------------------------------*/
namespace App\Models;

use CodeIgniter\Model;

class CrudModel extends Model
{
    protected $table = 'crud_data';       // Database table name
    protected $primaryKey = 'id';         // Primary key column
    protected $allowedFields = ['name', 'phone', 'address']; // Editable fields
    protected $useTimestamps = false;     // Set true if you use created_at / updated_at fields
    protected $returnType = 'object';     // Return results as objects

    /*
        Get all records
    */
    public function getAll()
    {
        return $this->findAll();
    }

    /*
        Get a specific record by ID
    */
    public function getById($id)
    {
        return $this->find($id);
    }

    /*
        Insert new record
    */
    public function saveRecord(array $data)
    {
        return $this->insert($data);
    }

    /*
        Update record by ID
    */
    public function updateRecord($id, array $data)
    {
        return $this->update($id, $data);
    }

    /*
        Delete record by ID
    */
    public function deleteRecord($id)
    {
        return $this->delete($id);
    }
}

Create View Files


We will now create the view files. The Views are the codes that what the user see and the code that the user can interact. We will create all these files:
  • layout/header_view.php
  • layout/footer_view.php
  • crud/index_view.php
  • crud/create_view.php
  • crud/edit_view.php
  • crud/show_view.php
application/views/layout/header_view.php

✂️ Copy and 📋 Paste 👇 


<!DOCTYPE html>
<html>
<head>
    <title>CodeIgniter CRUD</title>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.4.0/js/bootstrap.min.js" rel="stylesheet">
    <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
</head>
<body>
    <div class="container">

application/views/layout/footer_view.php

✂️ Copy and 📋 Paste 👇 


    </div>
    <center>CodeIgniter CRUD Created by <b>Luis A. Sierra</b></center>
    </body>
</html>


application/views/crud/index.php

✂️ Copy and 📋 Paste 👇 


<h2 class="text-center mt-5 mb-3"><?php echo $title; ?></h2>
<div class="card">
    <div class="card-header">
        <a class="btn btn-outline-primary" href="<?php echo base_url('crud/create/');?>">
            Create New Record
        </a>
    </div>
    <div class="card-body">
        <?php if (session()->getFlashdata('success')) {?>
            <div class="alert alert-success">
                <?php echo session()->getFlashdata('success'); ?>
            </div>
        <?php } ?>
 
        <table class="table table-bordered">
            <tr>
                <th>Name</th>
                <th>Phone</th>
                <th>Address</th>
                <th width="240px">Action</th>
            </tr>
 
            <?php foreach ($cruds as $crud) { ?>      
            <tr>
                <td><?php echo $crud->name; ?></td>
                <td><?php echo $crud->phone; ?></td>  
                <td><?php echo $crud->address; ?></td>                  
                <td>
                    <a
                        class="btn btn-outline-info"
                        href="<?php echo base_url('crud/show_page/'. $crud->id) ?>">
                        Show
                    </a>
                    <a
                        class="btn btn-outline-success"
                        href="<?php echo base_url('crud/edit/'.$crud->id) ?>">
                        Edit
                    </a>
                    <a
                        class="btn btn-outline-danger"
                        href="<?php echo base_url('crud/delete/'.$crud->id) ?>">
                        Delete
                    </a>
                </td>    
            </tr>
            <?php } ?>
        </table>
    </div>
</div>

application/views/crud/create_view.php

✂️ Copy and 📋 Paste 👇 


<h2 class="text-center mt-5 mb-3"><?php echo $title; ?></h2>
<div class="card">
    <div class="card-header">
        <a class="btn btn-outline-secondary" href="<?php echo base_url('crud/');?>">
            Back
        </a>
    </div>
    <div class="card-body">
        <?php if (session()->getFlashdata('errors')) {?>
            <div class="alert alert-danger">
                <?php echo session()->getFlashdata('errors'); ?>
            </div>
        <?php } ?>

        <form method="post" action="<?php echo base_url('crud/save'); ?>">
            <div class="form-group">
                <label for="name">Name:</label>
                <input type="text" class="form-control" id="name" name="name" placeholder="Enter name" value="<?php echo old('name'); ?>">
            </div>
            <div class="form-group">
                <label for="phone">Phone:</label>
                <input type="text" class="form-control" id="phone" name="phone" placeholder="Enter phone" value="<?php echo old('phone'); ?>">
            </div>
            <div class="form-group">
                <label for="address">Address:</label>
                <textarea class="form-control" id="address" name="address" placeholder="Enter address"><?php echo old('address'); ?></textarea>
            </div>
            <button type="submit" class="btn btn-success">Save</button>
        </form>
    </div>
</div>

application/views/crud/edit_view.php

✂️ Copy and 📋 Paste 👇 


<h2 class="text-center mt-5 mb-3"><?php echo $title; ?></h2>
<div class="card">
    <div class="card-header">
        <a class="btn btn-outline-secondary" href="<?php echo base_url('crud/');?>">
            Back
        </a>
    </div>
    <div class="card-body">
        <?php if (session()->getFlashdata('errors')) {?>
            <div class="alert alert-danger">
                <?php echo session()->getFlashdata('errors'); ?>
            </div>
        <?php } ?>

        <?php if (!empty($crud)) { ?>
            <form method="post" action="<?php echo base_url('crud/update/'.$crud->id); ?>">
                <?= csrf_field() ?>
                <input type="hidden" name="_method" value="PUT">
                <div class="form-group">
                    <label for="name">Name:</label>
                    <input type="text" class="form-control" id="name" name="name" placeholder="Enter name" value="<?php echo old('name', $crud->name); ?>">
                </div>
                <div class="form-group">
                    <label for="phone">Phone:</label>
                    <input type="text" class="form-control" id="phone" name="phone" placeholder="Enter phone" value="<?php echo old('phone', $crud->phone); ?>">
                </div>
                <div class="form-group">
                    <label for="address">Address:</label>
                    <textarea class="form-control" id="address" name="address" placeholder="Enter address"><?php echo old('address', $crud->address); ?></textarea>
                </div>
                <button type="submit" class="btn btn-success">Update</button>
            </form>
        <?php } else { ?>
            <p class="alert alert-warning">Record not found.</p>
        <?php } ?>
    </div>
</div>

application/views/crud/show_view.php

✂️ Copy and 📋 Paste 👇 


<h2 class="text-center mt-5 mb-3"><?php echo $title; ?></h2>
<div class="card">
    <div class="card-header">
        <a class="btn btn-outline-secondary" href="<?php echo base_url('crud/');?>">
            Back
        </a>
    </div>
    <div class="card-body">
        <?php if (!empty($crud)) { ?>
            <div class="form-group">
                <strong>Name:</strong>
                <p><?php echo $crud->name; ?></p>
            </div>
            <div class="form-group">
                <strong>Phone:</strong>
                <p><?php echo $crud->phone; ?></p>
            </div>
            <div class="form-group">
                <strong>Address:</strong>
                <p><?php echo $crud->address; ?></p>
            </div>
        <?php } else { ?>
            <p class="alert alert-warning">Record not found.</p>
        <?php } ?>
    </div>
</div>

Finally all the components are done.

Now we can test our CodeIgniter 4 Simple CRUD App by browsing this URL:

http://localhost:8080/crud

📷 Screenshots:

CodeIgniter 4 Simple CRUD App:









Congratulations 😎👏

Read more

Show more

Electron: Building for Mac, Windows and Linux

Electron: Building for Mac, Windows and Linux By: Luis A. Sierra Intro: Elec…

CodeIgniter 4 SQL-Server Simple CRUD Step-by-Step Tutorial

CodeIgniter 4 SQL-Server Simple CRUD Step-by-Step Tutorial CodeIgniter  is an  …

Load More That is All