Welcome, Guest
You have to register before you can post on our site.

Username
  

Password
  





Search Forums

(Advanced Search)

Forum Statistics
» Members: 1
» Latest member: admin
» Forum threads: 22
» Forum posts: 22

Full Statistics

Online Users
There are currently 3 online users.
» 0 Member(s) | 3 Guest(s)

Latest Threads
AI dalam Cyber Security, ...
Forum: My Forum
Last Post: admin
2 hours ago
» Replies: 0
» Views: 4
Favicon Getter
Forum: My Forum
Last Post: admin
3 hours ago
» Replies: 0
» Views: 3
Update Password di Larave...
Forum: My Forum
Last Post: admin
3 hours ago
» Replies: 0
» Views: 1
USB Multiboot
Forum: My Forum
Last Post: admin
3 hours ago
» Replies: 0
» Views: 2
Kustomisasi Halaman 404
Forum: My Forum
Last Post: admin
3 hours ago
» Replies: 0
» Views: 2
Event #001 Komunitas Back...
Forum: My Forum
Last Post: admin
3 hours ago
» Replies: 0
» Views: 2
Getting Started with Grap...
Forum: My Forum
Last Post: admin
3 hours ago
» Replies: 0
» Views: 1
Private: ElysiaJS Basic
Forum: My Forum
Last Post: admin
3 hours ago
» Replies: 0
» Views: 2
Private: Bexlite Course I...
Forum: My Forum
Last Post: admin
3 hours ago
» Replies: 0
» Views: 1
Stop Piracy
Forum: My Forum
Last Post: admin
3 hours ago
» Replies: 0
» Views: 4

 
  Getting Started with Jenkins
Posted by: admin - 3 hours ago - Forum: My Forum - No Replies

Quote:Reza Nurfachmi, January 5, 2025

Jenkins, sebelumnya bernama Hudson, adalah salah satu Open Source Automation Server yang populer sampai saat ini. Jenkins sangat memiliki banyak plugins yang membantu proses building, deploying, serta automating banyak jenis projek.

Quote:[Image: jenkins.jpg]


Jenkins dibangun menggunakan Java, pastikan kamu sudah menginstall SDK Java yang versi LTS. Untuk menginstall-nya, silahkan googling sendiri ya.
Prerequisites

Konfigurasi hardware yang direkomendasikan adalah:

    4 GB+ of RAM
    50 GB+ of drive space

Adapun software yang harus ada untuk menjalankan Jenkins, antara lain:

    Java: versi 11, 17, atau 21
    Browser: Google Chrome, Mozilla Firefox, Microsoft Edge, atau Apple Safari
    Git

Berikut adalah spesifikasi komputer yang penulis pakai:

Code:
git --version
git version 2.34.1

java --version
openjdk 21.0.5 2024-10-15
OpenJDK Runtime Environment (build 21.0.5+11-Ubuntu-1ubuntu122.04)
OpenJDK 64-Bit Server VM (build 21.0.5+11-Ubuntu-1ubuntu122.04, mixed mode, sharing)

Adapun Jenkins-nya penulis pakai versi 2.479.2 yang bisa diunduh di sini. Kalau versi lainnya, bisa diunduh di sini. Jika versi Java-mu berbeda, maka silahkan lihat halaman ini ya untuk menyesuaikan versi Jenkins-nya.

Setelah mengunduh file jenkins.war, silahkan jalankan perintah ini di path terletaknya file tersebut.

Code:
java -jar jenkins.war --httpPort=9090 &

Port-nya penulis ubah menjadi 9090 supaya beda aja. Defaultnya ia menggunakan port 8080.

Pastikan nanti muncul teks seperti ini:

Code:
Jenkins initial setup is required. An admin user has been created and a password generated.
Please use the following password to proceed to installation:

e0b2e5478******4ecd6a18a050

This may also be found at: /home/reza/.jenkins/secrets/initialAdminPassword

Kalau sudah muncul, maka buka browser dan arahkan ke alamat localhost:9090 atau sesuaikan saja jika kamu menginstall di cloud atau virtual machine.

[Image: jenkins-install.jpg?w=1007&ssl=1]

Isi dengan password yang diberikan, lalu klik tombol Continue.

---

Pada Costumize Jenkins, pilih Select plugins to install karena kita gak begitu butuh banyak plugin juga sih.

[Image: jenkins-plugins-selection.jpg?resize=640%2C343&ssl=1]

Pilih none lalu klik tombol Install.

[Image: jenkins-plugins-options.jpg?resize=640%2C578&ssl=1]

Selanjutnya adalah buat kredensial Administrator untuk Jenkins kamu. Jangan lupa klik tombol Save and Continue.

[Image: jenkins-admin-user.jpg?resize=640%2C584&ssl=1]

Terakhir pastikan instalasi Jenkins-nya. Lalu klik tombol Save and Finish.

[Image: jenkins-instance-config.jpg?resize=640%2C579&ssl=1]

Terakhir, klik tombol Start using Jenkins.

[Image: jenkins-is-ready.jpg?resize=640%2C577&ssl=1]

---

Daaan inilah tampilan Dashboard awalnya.

[Image: jenkins-dashboard.png?resize=640%2C549&ssl=1]

Nah, apa saja yang ada di dashboard ini?

Perhatikan sidebar paling bawah (Build Executor Status), di sana terdapat 2 worker yang nantinya akan menjalankan seluruh job yang kita tentukan untuk si Jenkins ini.

Quote:Karena satu dan lain hal, khususnya karena banyak issue teknis, pada praktik selanjutnya, tangkapan layar akan menggunakan Jenkins versi 2.479.2

[Image: jenkins-dashboard-2.png?resize=640%2C549&ssl=1]

Nah, barulah kita akan membuat Job baru setelah ini.

---

Membuat Job pada Jenkins

Klik pada menu Create a job atau New Item pada dashboard, selanjutnya kita harus mengisi nama jobnya.

[Image: jenkins-new-job.jpg?resize=640%2C278&ssl=1]

Setelah itu akan muncul halaman dengan banyak opsi yang bisa kita utak-atik. Kurang lebih tampilannya seperti ini:

[Image: jenkins-config-new-job.png?resize=640%2C814&ssl=1]

Silahkan isi deskripsinya lalu klik tombol Save.

[Image: jenkins-new-job.png?resize=640%2C549&ssl=1]

Nah, selesai tahap instalasi awal Job di Jenkins, selanjutnya kita akan mengintegrasikan projek kita yang ada di GitHub ke Jenkins ini.

---

Kalau kita kembali ke Dashboard lagi, maka halamannya sudah ada perubahan. Kini sudah ada Job yang telah kita buat tadi.

[Image: jenkins-dashboard-new-item.png?resize=640%2C368&ssl=1]

Pada tabel tersebut, tertulis N/A pada kolom Last Success, Last Failure dan Last Duration. Hal tersebut menandakan bahwa job kita belum pernah dijalankan sama sekali. Maka untuk menjalankannya, tinggal klik saja tombol ikon play warna hijau itu dan tunggu beberapa saat.

[Image: jenkins-first-build.png?resize=640%2C333&ssl=1]

Silahkan kamu klik Jobnya tersebut dan perhatikan ada perubahan apa saja yang terjadi ya. Harus mandiri. Hahaha.

Baik, kembali lagi ke urusan GitHub.

Pada awalnya, Jenkins tidak tau bagaimana caranya mengambil dan mengelola projek kita yang ada di GitHub. Maka dari itu kita harus menginstall plugin Git terlebih dahulu.

Kembali ke Dashboard, kemudian klik menu Manage Jenkins.

Lalu klik menu Plugins.

Klik menu Available plugins lalu ketikkan git sebagai keyword pencariannya.

Centang pada plugin Git, lalu pilih tombol Install after restart.

[Image: jenkins-install-plugin-git.png?resize=640%2C333&ssl=1]

Lalu halaman akan berpindah dan scroll ke paling bawah, centang opsi Restart Jenkins when installation is complete and no jobs are running dan tunggu hingga selesai instalasinya.

Pastikan kamu sudah setting SSH-nya ya. Kalau belum, bisa lihat video berikut.

Quote:https://www.youtube.com/watch?v=Fl91ObvW8tY

Oke, sampai sini penulis anggap kamu sudah selesai tahap SSH-nya. Karena selanjutnya ialah menghubungkan Jenkins dengan SSH.

Kembali lagi ke Dashboard, lalu klik Manage Jenkins. Cari menu Credentials. Kemudian klik menu (global).

[Image: jenkins-global-cred.jpg?resize=640%2C365&ssl=1]

Lalu klik tombol Add Credentials.

Berikut adalah pengaturan yang saya isi.

Kind: SSH Username with private key.

Scope: Global

ID: github-aaezha

Description: Credential GitHub AaEzha

Username: AaEzha

Private Key: Enter directly

Jika berhasil, maka muncul seperti ini:

[Image: jenkins-credential-success.png?resize=640%2C333&ssl=1]

Sampai di sini, kita seharusnya berhasil menyambungkan Jenkins dengan GitHub. Mari kita buktikan!

---

Kembali lagi ke Dashboard, pilih Job yang telah dibuat, pada kasus saya namanya Belajar Jenkins, lalu pilih menu Configure.

Pada opsi Source Code Management, pilih Git dan isi Repository URL projek kalian dan pastikan Credentials-nya adalah yang barusan dipilih serta tulis branch utama di opsi Branches to build.
Agar meyakinkan, coba dengan repositori privat yang kamu punya.

Misalnya seperti ini:

[Image: image.png?resize=640%2C627&ssl=1]

Lalu pada opsi Build Steps, klik dropdown Add build step, pilih Execute shell dan silahkan isi dengan perintah-perintah yang ingin dijalankan saat telah berhasil meng-clone repositori tersebut.

Karena repositori contoh saya adalah projek Laravel, maka saya ingin coba menambahkan satu perintah dahulu, yakni composer install dan ingin lihat hasilnya.

Lalu klik dulu tombol Save untuk memastikan bahwa kita telah berhasil dan tak ada error sampai sini.

[Image: image-1.png?resize=640%2C403&ssl=1]

Terakhir klik menu Build Now untuk testing konfigurasi di atas. Tunggu sebentar akan ada progress di pojok kiri bawah.

[Image: image-2.png?resize=394%2C319&ssl=1]

Silahkan klik pada angka #4 atau berapapun yang ada di layar kamu lalu klik menu Console Output untuk melihat proses yang terjadi.

[Image: image-3.png?resize=640%2C359&ssl=1]

Nampak pada punya saya lancar jaya, terlihat di sana ada tulisan composer install dan selanjutnya berjalan sebagaimana seharusnya.

Kalau kita klik kembali nama jobnya, lalu pilih menu Workspace, maka akan muncul direktori projek kita.

[Image: image-4.png?resize=640%2C532&ssl=1]

Nah, sampai sini kita sudah berhasil melakukan cloning dan menjalankan build steps. Silahkan tambahkan sendiri script atau command lainnya sesuai kebutuhan ya.

Etapipaaak, itu buildnya masih manual. Bagaimana caranya agar otomatis saat ada perubahan kode di repository, maka si build step ini berjalan sendiri tanpa bantuan kita? 

---

Mungkin ini tahap terakhir, yaitu membuat build step-nya berjalan otomatis saat ada perubahan pada branch yang kita set pada konfigurasi sebelumnya. Let’s go!

Kembali lagi ke halaman Job, kemudian pilih menu Configure.

Pada opsi Build Triggers, pilih opsi Poll SCM yang artinya si Jenkins akan melakukan build jika ada perubahan kode pada branch terpilih dalam rentang waktu yang ditentukan. Adapun rentang waktu yang paling minimal ialah setiap satu menit.

Code:
* * * * *

Kamu bisa isi dengan konfigurasi lainnya seperti mengatur cron. Lebih lengkapnya bisa baca di sini.

[Image: image-5.png?resize=640%2C234&ssl=1]

Jangan lupa klik tombol Save jika sudah selesai

Untuk membuktikannya, coba lakukan perubahan kode dan push ke repositori dan tunggu apakah Jenkins akan otomatis melakukan build? Jika iya, selamat kamu berhasil menamatkan Jenkins Level 1. Alhamdulillah.

Jangan sungkan untuk bertanya via komen ya kalau ada pertanyaan atau koreksi. Syukron udah mau baca sampai sini.

Print this item

  Getting Started with Cloudflare R2
Posted by: admin - 3 hours ago - Forum: My Forum - No Replies

Quote:Reza Nurfachmi, January 4, 2025

Cloudflare R2 Storage adalah layanan penyimpanan objek (object storage) yang dirancang sebagai alternatif dari solusi penyimpanan cloud tradisional seperti Amazon S3. R2 menawarkan cara untuk menyimpan data tidak terstruktur dalam jumlah besar, seperti file, gambar, video, atau dokumen, dengan fokus pada efisiensi biaya dan kinerja.

Quote:[Image: cloudflare.png?resize=381%2C376&ssl=1]

Keunggulan Utama Cloudflare R2
  • Tanpa Biaya Egress
Salah satu fitur paling menarik dari R2 adalah penghapusan biaya egress (bandwidth keluar), yang biasanya menjadi komponen mahal dalam layanan penyimpanan cloud lainnya.
  • Kompatibilitas dengan S3 API
R2 kompatibel dengan API Amazon S3, sehingga memudahkan pengembang untuk memigrasikan aplikasi atau integrasi yang sudah ada ke R2 tanpa banyak perubahan kode.
  • Skalabilitas Tinggi
R2 dirancang untuk menyimpan data dalam jumlah besar dengan ketersediaan dan skalabilitas tinggi.
  • Kinerja Optimal di Edge
Dengan jaringan edge Cloudflare yang luas, R2 memungkinkan pengiriman data yang cepat ke seluruh dunia, sehingga cocok untuk aplikasi yang memerlukan distribusi konten global.
  • Harga Kompetitif
Biaya penyimpanan dan operasional R2 sangat kompetitif dibandingkan dengan layanan serupa, menjadikannya solusi ekonomis untuk berbagai kasus penggunaan.

Bagaimana Cloudflare R2 Bekerja?

R2 menyimpan data dalam bentuk objek, mirip dengan layanan object storage lainnya. Setiap objek diidentifikasi dengan kunci unik, dan metadata dapat ditambahkan untuk mempermudah pengelolaan data. Dengan integrasi yang mendalam ke dalam jaringan Cloudflare, data yang disimpan di R2 dapat diakses dengan cepat melalui jaringan edge Cloudflare.

Jika kamu tertarik untuk mencoba Cloudflare R2, penulis akan menjelaskan langkah-langkah untuk mengintegrasikan R2 ke aplikasimu. ?

---

Berikut adalah langkah-langkah untuk mengintegrasikan Cloudflare R2 Storage ke aplikasi kamu, khususnya jika sudah familiar dengan Amazon S3 atau ingin memanfaatkan kompatibilitas S3 API:

Langkah 1: Siapkan Bucket di Cloudflare R2

Pertama, login ke akun Cloudflare kamu di Cloudflare Dashboard. Kalau belum punya akun, maka register dahulu.

Kedua, akses menu R2 Object Storage dari sidebar. Jika ini adalah pertama kali, seharusnya muncul halaman register R2 seperti ini:

[Image: register-r2.png?resize=640%2C465&ssl=1]

Jika seperti di atas, maka isi dulu formulir yang dibutuhkan. Tenang saja, kamu hanya akan ditagih jika melebihi batas pemakaian gratisannya kok.

Lalu bagaimana soal tarif Cloudflare R2 ini? Apa maksudnya Storage, Class A operations dan Class B operations?

[Image: free-tier-r2.jpg?resize=640%2C401&ssl=1]

Pada versi gratis, storage yang diberikan ialah sampai 10 GB per bulan. Jika lebih, maka akan kena biaya sebesar $0.015 per GB dari kuota berlebihnya. Jika ukuran storage kamu 15 GB, maka akan kena biaya sekitar $0.015 x 5 GB, yakni $0.075 atau setara dengan IDR 1.125 jika kurs di angka IDR 15.000.

Class A Operations, pada dasarnya adalah operasi yang cenderung mengubah status data, seperti menulis/upload atau memodifikasi objek, seperti PutObject (mengupload objek), CopyObject (menyalin objek), dan CompleteMultipartUpload (menyelesaikan upload multipart).

Adapun Class B Operations adalah operasi yang biasanya membaca status data yang ada tanpa mengubahnya. Contohnya ialah GetObject (mengambil objek) dan HeadObject (memeriksa metadata objek).

Baik, kembali lagi ke proses registrasi. Jika sudah berhasil memasukkan kredensial kartu kredit atau debit, maka akan muncul halaman seperti ini:

[Image: r2-dashboard.png?resize=640%2C299&ssl=1]

Selanjutnya adalah membuat Bucket. Apa itu Bucket? Bucket adalah keranjang yang isinya adalah objek-objek yang akan kita upload nanti.

Silahkan isi nama bucket-mu.

[Image: create-bucket.jpg?resize=640%2C574&ssl=1]

Jika berhasil, maka halamannya akan beralih seperti ini:

[Image: bucket-success.jpg?resize=640%2C345&ssl=1]

Cobalah upload satu file dulu. Jika berhasil, maka tampilannya sebagai berikut:

[Image: r2-upload-success.jpg?resize=640%2C296&ssl=1]

Saat ini, R2 kita hanya berlaku seperti flashdisk saja. Hanya bisa menyimpan data, tetapi belum bisa mengakses datanya secara online. Perhatikan pada bagian Public URL Access, di sana tertera Not allowed. Agar objek-objek yang kita upload bisa diakses, maka bagian tersebut harus berubah menjadi Allowed terlebih dahulu.

Caranya adalah klik menu Settings, lalu cari bagian Public Access sebagai berikut, kemudian klik tombol Allow Access.

[Image: r2-go-public.jpg?resize=640%2C115&ssl=1]

Lalu ikuti arahannya sampai berubah menjadi seperti ini:

[Image: r2-public-domain.jpg?resize=640%2C138&ssl=1]

Jika berhasil, maka saat masuk ke dalam objeknya, maka akan muncul URL publiknya sebagai berikut:

[Image: r2-public-url.jpg?resize=640%2C376&ssl=1]

Sampai sini, maka saatnya lanjut ke langkah berikutnya.

---

Langkah 2: Instalasi SDK atau Library

Gunakan library yang mendukung Amazon S3 untuk mengintegrasikan aplikasi kita dengan R2. Contoh library populer:

    PHP: AWS SDK for PHP
    Node.js: AWS SDK for JavaScript
    Python: Boto3
    Go: Minio Go SDK

Etapipaak, sebelum itu kita harus punya token API untuk dapat melakukan operasi menggunakan library di atas. Bagaimana caranya? Begini.

Arahkan kembali ke halaman Overview R2 Object Storage, kemudian arahkan seperti gambar di bawah. Pilih Manage API tokens.

[Image: r2-menu-create-token.jpg?resize=640%2C244&ssl=1]

Jika masih kosong, maka tampilannya sebagai berikut:

[Image: r2-token-empty-1024x228.jpg?resize=640%2C143&ssl=1]

Maka klik tombol Create API token untuk membuat satu. Berikut pengaturan penulis saat membuat token.

Token name: token-r2-read-write

Permissions: Object Read & Write: Allows the ability to read, write, and list objects in specific buckets.

Specify bucket(s): Apply to all buckets in this account (including newly created buckets)

TTL: Forever

Jika telah berhasil, maka silahkan simpan kredensial yang diberikan, antara lain:
  •     Token value
  •     Access Key ID
  •     Secret Access Key
  •     Default endpoint
  •     EU endpoint

Maka halamannya akan berubah menjadi seperti ini:

[Image: r2-token-exists-1024x206.jpg?resize=640%2C129&ssl=1]

Nah, selanjutnya kita akan mulai sedikit ngoding. Pada kali ini, saya contohkan pakai Laravel PHP ya.

---

Langkah 3: Contoh Kode Implementasi

Silahkan install Laravel fresh atau gunakan projek kamu yang ingin mengemplementasikan R2 ini.

Selanjutnya install package S3

PHP Code:
composer require league/flysystem-aws-s3-v3 "^3.0" --with-all-dependencies 

Code:
./composer.json has been updated
Running composer update league/flysystem-aws-s3-v3 --with-all-dependencies
Loading composer repositories with package information
Updating dependencies
Lock file operations: 4 installs, 3 updates, 0 removals
  - Locking aws/aws-crt-php (v1.2.7)
  - Locking aws/aws-sdk-php (3.336.7)
  - Upgrading guzzlehttp/promises (2.0.3 => 2.0.4)
  - Upgrading league/flysystem (3.29.0 => 3.29.1)
  - Locking league/flysystem-aws-s3-v3 (3.29.0)
  - Locking mtdowling/jmespath.php (2.8.0)
  - Upgrading symfony/deprecation-contracts (v3.5.0 => v3.5.1)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 4 installs, 3 updates, 0 removals
  - Downloading aws/aws-crt-php (v1.2.7)
  - Downloading mtdowling/jmespath.php (2.8.0)
  - Downloading aws/aws-sdk-php (3.336.7)
  - Downloading league/flysystem-aws-s3-v3 (3.29.0)
  - Installing aws/aws-crt-php (v1.2.7): Extracting archive
  - Upgrading symfony/deprecation-contracts (v3.5.0 => v3.5.1): Extracting archive
  - Upgrading guzzlehttp/promises (2.0.3 => 2.0.4): Extracting archive
  - Upgrading league/flysystem (3.29.0 => 3.29.1): Extracting archive
  - Installing mtdowling/jmespath.php (2.8.0): Extracting archive
  - Installing aws/aws-sdk-php (3.336.7): Extracting archive
  - Installing league/flysystem-aws-s3-v3 (3.29.0): Extracting archive
3 package suggestions were added by new dependencies, use `composer suggest` to see details.
Generating optimized autoload files
> Illuminate\Foundation\ComposerScripts::postAutoloadDump
> @php artisan package:discover --ansi

   INFO  Discovering packages. 

  laravel/sail .............................................................................. DONE
  laravel/tinker ............................................................................ DONE
  nesbot/carbon ............................................................................. DONE
  nunomaduro/collision ...................................................................... DONE
  nunomaduro/termwind ....................................................................... DONE

78 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
> @php artisan vendor:publish --tag=laravel-assets --ansi --force

   INFO  No publishable resources for tag [laravel-assets]. 

Found 4 security vulnerability advisories affecting 4 packages.
Run "composer audit" for a full list of advisories.

Oke, selanjutnya adalah tambahkan baris berikut ke file .env kita.

Code:
R2_ACCESS_KEY_ID=YOUR_ACCESS_KEY
R2_SECRET_ACCESS_KEY=YOUR_SECRET_KEY
R2_BUCKET=YOUR_BUCKET_NAME
R2_ENDPOINT=XXXXXXX.r2.cloudflarestorage.com

Lalu cari key FILESYSTEM_DISK dan ubah nilainya menjadi r2 seperti ini:

Code:
FILESYSTEM_DISK=r2

Kira-kira lengkapnya menjadi seperti ini:

Code:
FILESYSTEM_DISK=r2

// ...

R2_ACCESS_KEY_ID=17c995******b72dec******87976
R2_SECRET_ACCESS_KEY=fa55efa680d******5ecd898f06ae37761807f******b3bae36643f
R2_BUCKET=nurfachmi-academy
R2_ENDPOINT=https://9deccd0505******7560976cb3ff6.r2.cloudflarestorage.com

Beberapa value di atas sudah disensor dengan karakter *.

Selanjutnya tambahkan pengaturan disk di filesystem yang ada di config/filesystem.php.

PHP Code:
<?php

return [

    // ...

    'disks' => [

        // ...

       'r2' => [
            'driver' => 's3',
            'key' => env('R2_ACCESS_KEY_ID'),
            'secret' => env('R2_SECRET_ACCESS_KEY'),
            'region' => 'auto',
            'bucket' => env('R2_BUCKET'),
            'url' => env('R2_URL'),
            'endpoint' => env('R2_ENDPOINT'),
            'use_path_style_endpoint' => env('R2_USE_PATH_STYLE_ENDPOINT'false),
            'throw' => false,
        ],
    ],
]; 

Sip, sekarang kita beralih ke MVC-nya. Model, View, dan Controller. Let’s go!

---

Langkah 4: Model, View, dan Controller

Kita buat ketiganya dalam satu perintah.

PHP Code:
php artisan make:model Storage -mcr 

Code:
INFO  Model [app/Models/Storage.php] created successfully. 

   INFO  Migration [database/migrations/2025_01_04_005141_create_storages_table.php] created successfully. 

   INFO  Controller [app/Http/Controllers/StorageController.php] created successfully.

Dengan perintah di atas, kita membuat model Storage sekaligus migration dan resource controller.

---

Untuk migration, kita buat sederhana dulu saja seperti ini:

PHP Code:
<?php

// ...

return new class extends Migration
{
    public function up(): void
    
{
        Schema::create('storages', function (Blueprint $table) {
            $table->id();
            $table->string('path');
            $table->timestamps();
        });
    }

    // ...


Jalankan migratenya

PHP Code:
php artisan migrate 

File migration di atas setara dengan SQL command berikut:

PHP Code:
create table "storages" (
    "id" integer primary key autoincrement not null
    "path" varchar not null
    "created_at" datetime
    "updated_at" datetime
); 

---

Selanjutnya kita modifikasi file controllernya seperti ini:
PHP Code:
<?php

namespace App\Http\Controllers;

use 
Illuminate\Http\Request;

class 
StorageController extends Controller
{
    public function index()
    {
        return view('upload');
    }

    public function store(Request $request)
    {
        try {
            $path $request->file('file')->store('storage');

            $storage = new \App\Models\Storage();
            $storage->path $path;
            $storage->save();
        } catch (\Throwable $th) {
            dd($th->getMessage());
        }

        return back();
    }


Pada method index, kita sesederhana menampilkan view yang nanti berada di resources/views/upload.blade.php dan isinya berupa form upload saja dengan 2 elemen, yakni element input file dan tombol.

Adapun pada method store, hanya berupa usaha untuk upload file ke Cloudflare R2 dan menyimpannya ke dalam model Storage. Jika gagal, maka akan menampilkan errornya dalam fungsi dd. Jika berhasil, maka kembali ke halaman upload lagi.

Kita hanya menggunakan dua method itu saja dan silahkan hapus method lainnya karena tidak diperlukan.

--

Terakhir, buat file baru dengan nama upload.blade.php dalam folder resources/views dan isinya sesederhana berikut:

PHP Code:
<!DOCTYPE html>
<
html lang="en">

<
head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Upload to Cloudflare R2</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css">
</
head>

<
body class="container">

    <form action="{{ route('storage.store') }}" method="post" enctype="multipart/form-data">
        @csrf

        
<input type="file" name="file" id="file" required>

        <input type="submit" value="Upload">
    </form>

</
body>

</
html

--

Ups, sebelum kita coba di browser, kita harus menambahkan route juga di routes/web.php seperti ini:

PHP Code:
<?php

// ...

Route::resource('storage'\App\Http\Controllers\StorageController::class)
    ->only(['index''store']); 

--

Nah, saatnya pembuktian di browser!

---

Langkah 5: Pembuktian!

Silahkan jalankan web kita dengan perintah:

PHP Code:
php artisan serve 

Code:
   INFO  Server running on [http://127.0.0.1:8000]. 

  Press Ctrl+C to stop the server

Kemudian buka browser dan arahkan ke alamat http://localhost:8000/storage. Seharusnya muncul halaman seperti ini:

[Image: r2-upload-form.jpg?resize=532%2C139&ssl=1]

Silahkan coba upload satu gambar atau file.

Pastikan di bucket kamu sudah bertambah 1 objek baru. Jika tidak, berarti masih ada yang keliru dari langkah-langkah sebelumnya. Silahkan diperiksa kembali.

[Image: r2-success-upload.jpg?resize=640%2C291&ssl=1]

Nampak ada satu file terupload di folder dengan nama storage dalam bucket nurfachmi-academy tersebut.

Nah, demikian deh cara integrasi Cloudflare R2 ke dalam Laravel, sekaligus mengenalkan apa itu Cloudflare R2. Ada pertanyaan? Silahkan tanya di kolom komentar ya!

Salam.

[Image: cloudflare-r2.png]

Print this item

  Tech Bro vs Anak Seni
Posted by: admin - 4 hours ago - Forum: My Forum - No Replies

Quote:Reza Nurfachmi, July 16, 2024

Bismillahirrahmanirrahim

Sesekali ingin menuangkan pendapat yang ada di benak sejenak setelah baca tweet ini.

Twitter

[Image: IamProgrammerEnglish.png]

Latar Belakang

Mengapa tech bro seperti ndak tergeser keberadaannya dengan AI? Karena kami, ya saya juga termasuk tech bro karena berprofesi di bidang teknologi ~khususnya sebagai software engineer~, memanfaatkan AI untuk memudahkan pekerjaan. Lantas mengapa anak seni terlihat seperti melawan keberadaan AI?

Rumusan Masalah

IMHO karena anak seni belum memiliki wadah, semacam layanan AI, yang memudahkan pekerjaannya. Andaikan ada, maka lain cerita.

Banyak AI Image Generator bertebaran di internet, dari yang gratis hingga yang nguras kantong abis. Namun, menurutku tetap kurang mengakomodir kebutuhan mereka.

Masalah Penulis

Sejujurnya saya tidak memiliki pengetahuan apa-apa tentang seni dan menulis artikel ini pun tanpa bertanya-tanya dahulu ke anak seni satu pun. Jadi ini murni pendapat pribadi. Bahkan saya pun hanya penikmat layanan AI dan belum bisa membuat layanan menggunakan AI.

Entah, jadi bingung nulis akar masalahnya yang dialami anak seni ini. Etapi saya kurang suka terlalu fokus dengan masalah. Lebih senang banyak menghabiskan waktu untuk mencari jalan keluar.

Pembahasan

Saya hanya membayangkan jika ada servis AI yang flownya benar-benar dapat membantu para anak seni ini. Jadi ndak hanya sekedar menulis prompt yang benar, tetapi juga dataset yang digunakan sesuai dengan yang mereka kehendaki.

Kira-kira begini flownya.
  1. User mendaftarkan dirinya ke website atau aplikasi gawai.
  2. User memasukkan referensi gambar-gambar yang biasa ia hasilkan atau yang menjadi referensi sebagai keluaran hasilnya nanti.
  3. User menunggu beberapa waktu untuk sistem dapat “belajar” dari materi-materi yang diberikan pada poin sebelumnya.
  4. Setelah siap, user mendapatkan notifikasi dan mulai dapat menuliskan prompt yang ia inginkan dan hasilnya pun sesuai dengan referensi yang diinput.

Lalu apa bedanya dengan AI Image Generator pada umumnya? Berikut kira-kira perbedaannya, atau bisa dibilang sebagai “keuntungan”-nya.

Meminimalisir pencurian hak cipta.

Dilansir bahwa AI Image Generator banyak melakukan pencurian hak cipta karena memakai sembarang gambar untuk dipelajari oleh AI mereka tanpa izin atau sepengetahuan pemilik gambar. Dengan flow di atas, maka si layanan AI ini hanya memakai sumber data yang diberikan oleh User. Jadi jika terjadi penuntutan atas pelanggaran hak cipta, maka bisa langsung ditujukan kepada User, bukan layanan AI-nya.

WYGIWYG

Kalau di skena Tech Bro ada WYSIWYG (baca: wisiwig) (What You See is What You Get), maka dengan flow di atas anak seni dapat WYGIWYG (baca: wigiwig) (What You Give is What You Get). Artinya hasil prompt yang diberikan akan selalu merujuk kepada materi-materi yang ia berikan sendiri kepada si AI.

Memudahkan Anak Seni

Dengan dua keuntungan sebelumnya, maka saya rasa layanan AI tersebut akan menjadi salah satu alat yang sangat amat memudahkan pekerjaan si anak seni tersebut. Setelah memberikan prompt, layanan AI akan memberikan beberapa sugesti hasil yang kemudian bisa langsung dipakai atau hanya dijadikan referensi yang nanti akan dikerjakan secara manual oleh tangannya si anak seni tersebut.

Penutup

Yah begitulah kira-kira yang ada dalam benak saya mengenai perseteruan pada tweet di atas. Maafkan jika ada kekurangan.

Print this item

  Mengatur ID Increment Selanjutnya pada PostgreSQL dan MySQL
Posted by: admin - 4 hours ago - Forum: My Forum - No Replies

Quote:Reza Nurfachmi, July 29, 2024

Bismillahirrahmanirrahim

Bermula dari error yang saya temukan saat ingin menambahkan data lewat CMS dan keharusan saya untuk menuliskan nilai pada kolom “id” yang seharusnya terisi sendiri meski dikosongkan, maka saya mengambil keputusan bahwa ada yang keliru dengan nilai increment selanjutnya. Sebenarnya, kesulitan saya ini terjadi di PostgreSQL karena untuk menentukan nilai increment selanjutnya tidak semudah di MySQL dengan DBeaver sebagai Database GUI utama.

[Image: postgresql.jpeg]

Pada MySQL, untuk menentukan nilai auto-increment selanjutnya bisa dilihat dan ditentukan tanpa menggunakan query. Cukup lihat pada properties tabel yang diinginkan, lalu ubah dan klik simpan.

[Image: 419e6b22-147e-4893-836f-296697984edf.png?w=640&ssl=1]

Pada PostgreSQL, tampilan properties tabelnya tidak seperti di atas, melainkan seperti ini:

[Image: cc4ba708-628a-4acc-a351-bebcdd24b948.png?w=640&ssl=1]

Tidak terlihat pengaturan auto-increment-nya, kan?

Yah begitu lah keterbatasan Database GUI Editor, tidak akan semudah dan sefleksibel command line pada terminal.

Setelah googling sana-sini, beginilah cara mengetahui nilai increment selanjutnya dan cara mengatur nilai increment selanjutnya pada PostgreSQL maupun MySQL.

PostgreSQL

Mengetahui nilai increment selanjutnya

Code:
SELECT nextval('nama_sequence');

Pertanyaannya, bagaimana mengetahui nama_sequence pada tabel tertentu itu?

Pada DBeaver, hal itu bisa didapatkan dengan melihat tab Columns dan nilai kolom Defaultnya.

[Image: 58ad0d54-b6f1-4be0-ac7d-900318238679.png?w=640&ssl=1]

Namun, untuk mendapatkan nama_sequence menggunakan query adalah sebagai berikut:

Code:
SELECT pg_get_serial_sequence('nama_tabel', 'nama_kolom');

-- contoh:
SELECT pg_get_serial_sequence('staff', 'id');

-- contoh response:
-- public.staff_id_seq

Maka, selanjutnya tinggal dibungkus menjadi string dan ditambahkan identifikasi kelas (class) dengan akhiran ::regclass dan tanpa awalan public.-nya.

Hasil akhirnya adalah berupa sequence_name : ‘staff_id_seq’::regclass

Untuk mendapatkan nilai increment selanjutnya, bisa dengan query berikut:

Code:
SELECT nextval('staff_id_seq'::regclass);

-- output
-- kolom : nextval
-- nilai : 853

Mengatur nilai increment selanjutnya

Code:
SELECT setval('nama_sequence', nilai_baru);

Jika mengikuti contoh kolom di atas, maka query lengkapnya akan seperti ini:

Code:
SELECT setval('staff_id_seq'::regclass, 860);

MySQL

Mengetahui nilai increment selanjutnya

Ada dua cara atau query untuk mendapatkan hal tersebut, yakni query panjang dan pendek. Mari kita mulai dengan query panjang dahulu, yaitu seperti ini:

Code:
SELECT AUTO_INCREMENT
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = 'nama_database'
AND TABLE_NAME = 'nama_tabel';

Contohnya seperti ini:

Code:
SELECT AUTO_INCREMENT
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = 'daycare'
AND TABLE_NAME = 'staff';

-- output
-- kolom : AUTO_INCREMENT
-- nilai : 853

Adapun query pendeknya bisa seperti ini :

Code:
SHOW TABLE STATUS LIKE 'nama_tabel';

Contohnya seperti ini:

Code:
SHOW TABLE STATUS LIKE 'staff';

-- output
-- kolom : Auto_increment
-- nilai : 853

Kemudian lihat hasil pada kolom ‘Auto_increment’. Angka yang tampil adalah yang menjadi nilai increment selanjutnya.

Mengatur nilai increment selanjutnya

Untuk mengatur atau override nilai increment selanjutnya, bisa dicapai dengan query berikut:

Code:
ALTER TABLE nama_tabel AUTO_INCREMENT = nilai_baru;

Contohnya seperti ini:

Code:
ALTER TABLE staff AUTO_INCREMENT = 860;

---

Ya, kira-kira demikian untuk mengetahui dan mengatur nilai increment selanjutnya pada PostgreSQL dan MySQL. Maafkan jika ada kekurangan dan mohon koreksi jika ada kekeliruan.

Print this item

  Class Ajaib di Laravel
Posted by: admin - 4 hours ago - Forum: My Forum - No Replies

Quote:Reza Nurfachmi, March 28, 2023

Tau nggak sih kenapa barisan kode sederhana seperti ini bisa mengeluarkan output dengan berbagai cara?
PHP Code:
$user \App\Models\User::inRandomOrder()->first(); 

Dengan keluaran sebagai array, bisa…
PHP Code:
$user['name']; // output: John 

Dengan keluaran sebagai object, bisa juga…
PHP Code:
$user->name// output: John 

Jawabannya adalah karena ada suatu class yang namanya Fluent. Class ini secara ajaib melakukan mutasi kepada data agar bisa diakses dalam berbagai metode. Salah duanya adalah seperti yang sudah penulis jabarkan di atas.

Sebelum penulis berikan berbagai contoh penggunaannya, mari kita kenalan dengan class Fluent ini.

PHP Code:
use Illuminate\Support\Fluent;

$attributes = ['name' => 'Reza'];
$data = new Fluent($attributes); 

Selanjutnya adalah ada berbagai metode yang bisa dilakukan oleh class Fluent ini. Penulis langsung jabarkan melalui contoh satu per satu ya.

---

PHP Code:
$data->get('name''Nurfachmi'); 

Kode di atas akan mengembalikan nilai dari name atau Nurfachmi jika name belum di-set nilainya.

---

PHP Code:
$data->getAttributes(); 

Kode di atas akan mengembalikan seluruh atribut yang sudah di-set, termasuk yang baru dibuat, misalnya:

PHP Code:
$data->last_name "Nurfachmi";

print_r($data->getAttributes());
/***
Output:
Array ( [name] => Reza [last_name] => Nurfachmi )
***/ 

---

PHP Code:
$data->toArray(); 

Kode di atas akan mengembalikan data sebagai array.

---

PHP Code:
$data->toJson(); 

Kode di atas akan mengembalikan data sebagai json.

---

Fluent adalah sebuah utiliti class yang disediakan oleh Laravel sendiri agar kita dapat secara luwes mengolah data.

Print this item

  Laravel Blueprint Macro
Posted by: admin - 4 hours ago - Forum: My Forum - No Replies

Quote:Reza Nurfachmi, July 13, 2024

Bismillahirrahmanirrahim

Apakah kamu pernah merancang desain struktur database dan menemukan bahwa ada beberapa kolom yang hampir selalu ada di setiap tabelnya? Lebih memukau lagi bahwa kamu selalu menulis ulang di setiap file migration-nya? Apakah ada cara agar kamu tidak menulis ulang kolom-kolom tersebut di hampir setiap file migration yang ada?

Studi Kasus

Misalnya saya selalu ingin memasukkan beberapa kolom ini:
  • created_by
  • updated_by
  • deleted_by
  • created_at
  • updated_at
  • deleted_at


Maka di setiap file migration harus selalu ada baris ini:
PHP Code:
$table->string('created_by'150)->nullable()->default('Sistem');
$table->string('updated_by'150)->nullable()->default('Sistem');
$table->string('deleted_by'150)->nullable();
$table->timestamps();
$table->softDeletes(); 

Sudah terbayang bagaimana repotnya untuk melakukan copy-paste setiap menambah file migration baru?

---

Solusi

Ada 2 cara yang saya tau untuk menangani masalah perulangan di atas, antara lain:

  1. Lewat file AppServiceProvider.php yang terdapat di folder app/Providers.
  2. Menggunakan Trait.

Keduanya tetap memanfaatkan fitur Macro pada Blueprint. Pada artikel ini saya mengesampingkan teori dan lebih mengedepankan prakteknya.

Mari kita mulai ngoding!

Lewat AppServiceProvider

Dalam function boot, tambahkan kode berikut:
PHP Code:
// Blueprint Macro
Blueprint::macro('opsFields', function () {
    $this->string('created_by'150)->nullable()->default('Sistem');
    $this->string('updated_by'150)->nullable()->default('Sistem');
    $this->string('deleted_by'150)->nullable();
    $this->timestamps();
    $this->softDeletes();
}); 

Maka jika kamu butuh kolom-kolom tersebut dalam file migration, maka cukup tambahkan saja $table->opsFields() di dalamnya. Contohnya jadi seperti ini:
PHP Code:
Schema::create('categories', function (Blueprint $table) {
    $table->id();
    $table->string('code'7)->unique();
    $table->string('name'150);
    $table->opsFields();
}); 

Menggunakan Trait

Buat sebuah class baru dengan perintah php artisan make:trait OpsFields dan tuliskan isinya sebagai berikut:
PHP Code:
public function opsFields(Blueprint $table): void
{
    $table->string('created_by'150)->nullable()->default('Sistem');
    $table->string('updated_by'150)->nullable()->default('Sistem');
    $table->string('deleted_by'150)->nullable();
    $table->timestamps();
    $table->softDeletes();


File trait selengkapnya jadi seperti ini:
PHP Code:
<?php

namespace App\Traits;

use 
Illuminate\Database\Schema\Blueprint;

trait 
OpsFields
{
    public function opsFields(Blueprint $table): void
    
{
        $table->string('created_by'150)->nullable()->default('Sistem');
        $table->string('updated_by'150)->nullable()->default('Sistem');
        $table->string('deleted_by'150)->nullable();
        $table->timestamps();
        $table->softDeletes();
    }


Maka jika kamu butuh kolom-kolom tersebut dalam file migration, maka cukup tambahkan saja $table->opsFields() di dalamnya. Contohnya jadi seperti ini:
PHP Code:
Schema::create('categories', function (Blueprint $table) {
    $table->id();
    $table->string('code'7)->unique();
    $table->string('name'150);
    $this->opsFields($table);
}); 

Jangan lupa tambahkan namespace pada bagian atas file migration-nya:
PHP Code:
use App\Traits\OpsFields

Selengkapnya jadi seperti ini file migration-nya:
PHP Code:
<?php

use App\Traits\OpsFields;
use 
Illuminate\Database\Migrations\Migration;
use 
Illuminate\Database\Schema\Blueprint;
use 
Illuminate\Support\Facades\Schema;

return new class extends 
Migration
{
    use OpsFields;
    /**
     * Run the migrations.
     */
    public function up(): void
    
{
        Schema::create('categories', function (Blueprint $table) {
            $table->id();
            $table->string('code'7)->unique();
            $table->string('name'150);
            $this->opsFields($table);
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    
{
        Schema::dropIfExists('categories');
    }
}; 

Hasil

Jika kamu coba jalankan perintah di terminal sebagai berikut php artisan migrate --pretend, maka akan menghasilkan query sebagai berikut:
PHP Code:
create table `categories` (
   `idbigint unsigned not null auto_increment primary key
   `codevarchar(7not null
   `namevarchar(150not null
   `created_byvarchar(150null default 'Sistem'
   `updated_byvarchar(150null default 'Sistem'
   `deleted_byvarchar(150null
   `created_attimestamp null
   `updated_attimestamp null
   `deleted_attimestamp null
) default character set utf8mb4 collate 'utf8mb4_unicode_ci';

alter table `categoriesadd unique `categories_code_unique`(`code`); 

Nah, silahkan kamu pilih mau pakai metode yang mana. Apakah lewat service provider atau trait. Pilihan saya? Trait. Mengapa?

Jika menggunakan Trait, maka ia akan hadir jika dipanggil saja. Adapun jika service provider, sejatinya ia akan selalu dipanggil di setiap request, tentang migration atau lainnya.

Print this item

  Membuat Blade Directive Sendiri
Posted by: admin - 4 hours ago - Forum: My Forum - No Replies

Quote:Reza Nurfachmi, August 2, 2022

Sebagai salah satu programmer yang menggunakan Laravel, tentunya setiap hari saya berjibaku dengan file berekstensikan *.blade.php. Tak jarang pula saya membuat beberapa fungsi untuk mempermudah hal-hal yang sulit atau berulang. Salah satu yang sering saya lakukan adalah untuk menampilkan data uang.

[Image: laravel.png]

Misalnya, dari database hanya menampilkan 150000, tetapi saya ingin hasil akhirnya adalah IDR 150.000.

Normalnya akan melakukan hal seperti ini:

PHP Code:
<p>IDR {{ number_format($data->price0',''.') }}</p

Namun, saya melakukannya dengan cara lain, yakni seperti ini:

PHP Code:
<p>@idr($data->price)</p

Bagaimana cara melakukannya?

Insyaallah mudah. Yuk sambil dipraktekkan.

Caranya adalah dengan mendaftarkan directive blade kita ke app/Providers/AppServiceProvider.php di dalam method boot().

PHP Code:
<?php

use Illuminate\Support\Facades\Blade;

public function 
boot()
{
    Blade::directive('idr', function ($value) {
        return "<?php echo 'IDR ' . number_format($value, 0, ',', '.'); ?>";
    });


Perhatikan bahwa kita tidak hanya me-return string biasa, melainkan lengkap dengan tag pembuka dan penutup serta echo-nya seakan menuliskan kode PHP di dalam PHP. Mengapa demikian?

Karena directive ini akan dijalankan di tengah-tengah blok kode HTML, meskipun ekstensi filenya .php.

Kalau teman-teman ingin mendaftarkan blade directive lainnya, silahkan tambahkan saja di bawah barisan kode tadi ya.

Atau jika tidak ingin aktif secara global dan hanya untuk file atau controller tertentu, maka cukup tuliskan saja pada method tersebut. Misalnya hanya ingin di controller dan method tertentu, maka bisa begini:

PHP Code:
<?php

use Illuminate\Support\Facades\Blade;

public function 
index()
{
    Blade::directive('idr', function ($value) {
        return "<?php echo 'IDR ' . number_format($value, 0, ',', '.'); ?>";
    });

    return view('blade-directives.controller');


Happy coding!

Print this item

  Elisitasi
Posted by: admin - 4 hours ago - Forum: My Forum - No Replies

Quote:Reza Nurfachmi, November 8, 2022

Sesungguhnya ini hanyalah catatan dari apa yang saya pelajari saat kuliah. Saya lupa mata kuliah apa tepatnya. So, mari kita lanjutin aja yaaa…

Elisitasi adalah seperangkat data terkait kebutuhan sistem baru dari aktivitas pengguna sistem atau stakeholder yang memiliki keterkaitan/hubungan langsung dengan penggunaan sistem maupun dengan pengembangan sistem.

Sederhananya, proses elisitasi adalah proses eliminasi terhadap requirements dari user melalui 3 tahap dan final elisitasi.

Elisitasi Tahap 1

Berisi seluruh rancangan sistem baru yang diusulkan oleh pihak manajemen terkait melalui proses wawancara.

Elisitasi Tahap 2

Merupakan hasil pengklasifikasian dari elisitasi tahap I berdasarkan metode MDI. Metode MDI ini bertujuan untuk memisahkan antara rancangan sistem yang penting dan harus ada pada sistem baru dengan rancangan yang disanggupi oleh penulis untuk dieksekusi.
  • “M” pada MDI itu artinya Mandatory (penting). Maksudnya requirement tersebut harus ada dan tidak boleh dihilangkan pada saat membuat sistem baru.
  • “D” pada MDI itu artinya Desirable. Maksudnya requirement tersebut tidak terlalu penting dan boleh dihilangkan. Tetapi jika requirement tersebut digunakan dalam pembuatan sistem, akan membuat sistem tersebut lebih sempurna.
  • “I” pada MDI itu artinya Inessential. Maksudnya bahwa requirement tersebut bukanlah bagian dari sistem yang dibahas dan merupakan bagian dari luar sistem.

Elisitasi Tahap 3

Merupakan hasil penyusutan dari elisitasi tahap II dengancara mengeliminasi semua requirement yang optionnya I pada metode MDI. Selanjutnya semua requirement yang tersisa diklasifikasikan kembali melalui metode TOE, yaitu sebagai berikut:
  • T artinya Technical, maksudnya bagaimana tata cara/teknik pembuatan requirement tersebut dalam sistem yang diusulkan.
  • O artinya Operational, maksudnya bagaimana tata cara penggunaan requirement tersebut dalam sistem yang akan dikembangkan.
  • E artinya Economy, maksudnya berapakah biaya yang diperlukan guna membangun requirement tersebut didalam sistem.

Metode TOE tersebut dibagi kembali menjadi beberapa option, yaitu:
  • High (H) : Sulit untuk dikerjakan, karena tehnik pembuatan dan pemakaiannya sulit serta biayanya mahal, sehingga requirement tersebut harus dieliminasi.
  • Middle (M) : Mampu untuk dikerjakan.
  • Low (L) : Mudah untuk dikerjakan.

Draft Final Elisitasi

Merupakan hasil akhir yang dicapai dari suatu proses elisitasi yang dapat digunakan sebagai dasar pembuatan suatu sistem yang akan dikembangkan.
Biar gak bingung, mari kita lihat contohnya saja ya.

Elisitasi Tahap 1

[Image: elisitasi-1.png?resize=327%2C607&ssl=1]

Elisitasi Tahap 2

[Image: elisitasi-2.png?resize=354%2C520&ssl=1]

Elisitasi Tahap 3

[Image: elisitasi-3.png?resize=366%2C601&ssl=1]

Final Draft Elisitasi

[Image: elisitasi-final.png?resize=322%2C617&ssl=1]

Hasil di atas tentu belum final, karena masih sebagai Draft. Semuanya masih bisa diolah lagi, bahkan bisa berulang ke Tahap 1 lagi berdasarkan data pada Final Draft-nya.

Nah, kurang lebih demikian tentang elisitasi.

Sumber: Widuri

Print this item

  EduWork Logic Test
Posted by: admin - 5 hours ago - Forum: My Forum - No Replies

Quote:Reza Nurfachmi, July 28, 2022

Beberapa bulan terakhir ini, saya terdaftar menjadi salah satu mentor di sebuah platform mentorship yang juga menjanjikan pekerjaan untuk para siswanya. Namun, foto saya tidak terpampang di situ karena bukan termasuk pekerja di perusahaan start-up terkemuka. Hihihi.

Setelah beberapa bulan berjalan, sampailah siswa-siswa saya dianggap “lulus” dan harus mengerjakan soal mengenai logika. Begini soalnya dan begitu jawaban dari saya. Hihihi.
Harus diingat, jawaban ini bukanlah satu-satunya jawaban dan belum tentu jawaban terbaik. Jadi, silahkan kirimkan komentar kalau teman-teman punya jawaban yang lebih baik ya.

---

Quote:Buatlah fungsi sebagai berikut :
Apabila terdapat int = 4, maka outputnya 24 (prosesnya : 4*3*2*1)
Apabila terdapat int = 8, maka outputnya 40320 (prosesnya : 8*7*6*5*4*3*2*1)

Jawaban:
PHP Code:
<?php

$int 
4// ubah angka di sini

for($i $int 1$i >= 1$i--) {
    $int *= $i;
}

echo 
$int// output: 24 

---

Quote:Buatlah fungsi untuk reverse sebuah string
Apabila input = “abcde”, maka outputnya = “edcba”
Dilarang menggunakan function reverse, buatlah logika sendiri

Jawaban:
PHP Code:
<?php

$input 
"abcde";

$n strlen($input);

for (
$i 1$i <= $n$i++) {
  $val $input[-$i];
  echo $val;
}

// output: edcba 

---

Quote:Buatlah fungsi untuk menampilkan jumlah digit angka tergantung dimana posisi atau tempat dari angka dalam sebuah string “9.86-A5.321”!
Contoh: printDigitValue(‘9.86-A5.321’);
Hasil :
9865321
9000000
800000
60000
5000
300
20
1

Jawaban:
PHP Code:
<?php

echo printDigitValue('9.86-A5.321');

function 
printDigitValue($value)
{
  $n strlen($value);
  $result "";

  for ($i 0$i <= $n$i++) {
    if (!is_numeric($value[$i])) {
      continue;
    }
    $result .= $value[$i];
  }

  echo $result "\n";

  $n strlen($result);

  for ($i 0$i <= $n$i++) {
    echo str_pad($result[$i], $n $i'0'STR_PAD_RIGHT) . "\n";
  }


---

Quote:Ketik kode untuk swap 2 integer variables tanpa VARIABLE TAMBAHAN
Contoh : let a = 3, let b = 7 => hasilnya a = 7, b = 3

Jawaban:
PHP Code:
<?php

$a 
3;
$b 7;

$a $a $b;
$b $a $b;
$a $a $b

---

Quote:Buatlah fungsi sebagai berikut :
int : 4, maka outputnya adalah : empat
int : 20, maka outputnya adalah : dua puluh
int : 39, maka outputnya adalah : tiga puluh sembilan
int : 104, maka outputnya adalah : silahkan masukkan bilangan 1-100

Jawaban:
PHP Code:
<?php

$angka 
101;
echo 
penyebut($angka);

function 
penyebut($nilai)
{
  $nilai abs($nilai);
  $huruf = array("""satu""dua""tiga""empat""lima""enam""tujuh""delapan""sembilan""sepuluh""sebelas");
  $temp "";
  if ($nilai <= or $nilai 100) {
    echo "silahkan masukkan bilangan 1-100";
  } else if ($nilai 12) {
    $temp " " $huruf[$nilai];
  } else if ($nilai 20) {
    $temp penyebut($nilai 10) . " belas";
  } else if ($nilai 100) {
    $temp penyebut($nilai 10) . " puluh" penyebut($nilai 10);
  } else {
    echo "seratus";
  }

  return $temp;


---

Quote:Apabila terdapat sebuah data :
array data =  [1,4,7,9,12],
int low = 2,
int high = 15,
maka akan menghasilkan ouput [4,7,9,12]

Jawaban:
PHP Code:
<?php

$array 
= [147912];
$low 2;
$high 15;

$result = [];

foreach (
$array as $key => $value) {
  if ($value >= $low && $value <= $high) {
    $result[] = $value;
  }
}

var_dump ($result); 

---

Quote:Dari soal nomor 6, buatlah juga untuk menghasilkan output total ada berapa angka yg termasuk dari bagian low dan high
array data =  [1,4,7,9,12],
int low = 2,
int high = 15,
maka akan menghasilkan ouput = 4

Jawaban:
PHP Code:
<?php

$array 
= [147912];
$low 2;
$high 15;

$result = [];

foreach (
$array as $key => $value) {
  if ($value >= $low && $value <= $high) {
    $result[] = $value;
  }
}

echo 
count($result); 

---

Quote:Apabila terdapat int = 15, maka akan mencetak output berikut :
1
2
Edu
4
Work
6
7
8
Edu
10
11
Edu
13
14
EduWork

keterangan : string edu untuk kelipatan 3, string work untuk kelipatan 5, string eduwork untuk kelipatan 3 dan 5

Jawaban:
PHP Code:
<?php

$int 
15;

for (
$i=1$i <= $int$i++) { 
  if ($i == && $i == 0) {
    echo "EduWork";
  } else if ($i == 0) {
    echo "Edu";
  } else if ($i == 0) {
    echo "Work";
  } else {
    echo $i;
  }


---

Quote:Buatlah fungsi untuk menentukan bilangan terkecil dan terbesar dari sebuah array
Contoh : array [4,2,6,88,3,11]
Maka outputnya adalah low : 2, high : 88
dilarang menggunakan built in function

Jawaban:
PHP Code:
<?php

$array 
= [42688311];
$low $array[0];
$high $array[0];
$n count($array);

for (
$i 0$i $n$i++) {
  if ($low $array[$i]) { 
    $low $array[$i]; 
  

  if ($high $array[$i]) {
    $high $array[$i];
  }
}

echo 
"low : $low, high : $high"

---

Quote:Buatlah fungsi untuk mengecek tahun kabisat
input : 2021
output : 2021 bukan tahun kabisat

input : 2024
output : 2024 adalah tahun kabisat

Jawaban:
PHP Code:
<?php

$input 
2021;

if (
$input == 0) {
  echo "$input adalah tahun kabisat";
} else if (
$input != 0) {
  echo "$input bukan tahun kabisat";


---

Perhatian. Jangan anggap ini sebagai kunci jawaban karena EduWork bisa mengubah soal-soal di atas kapan pun. Yang saya ingin sampaikan adalah PAHAMI jawaban-jawaban di atas sehingga logika kita bisa semakin terasah jika diberikan soal logika lainnya.

Print this item

  User root MySQL Tetiba Tidak Berfungsi
Posted by: admin - 5 hours ago - Forum: My Forum - No Replies

Quote:Reza Nurfachmi, July 29, 2022

Pagi ini saya mendapatkan notifikasi untuk update versi MySQL terbaru pada laptop yang terinstall LinuxMint dan dipakai rutin untuk kerja setiap hari. Tentunya lebih banyak antara Senin sampai Jum’at saja, karena work life balance itu perlu dan penting.

Tepat setelah update, saya mulai membuka projek Laravel dan mendapati bahwa ada kesalahan password pada user root yang dipakai.

Code:
$ mysql -uroot -p
Enter password:
ERROR 1698 (28000): Access denied for user 'root'@'localhost'

Jeng jeng…

Bingung lah saya mendapati error seperti itu yang bahkan kurang dari 24 jam lalu masih lancar jaya gemah ripah low jinawi!

Apa yang terjadi dengan laptop saya? Apakah ada yang mencoba mengirim santet ke user root saya? Apakah user root saya terkena dampak inflasi negara Sri Lanka?
Selidik punya selidik, saya tidak menemukan alasan kenapa semua ini bisa terjadi dan menimpa seorang ayah dengan 1 anak dan 1 istri ini. Namun, solusinya cukup sederhana sesuai dengan pengalaman saya selama ini.

Saya coba login menggunakan sudo, alhamdulillah bisa. Kemudian saya tuliskan 1 baris sederhana yang mungkin nantinya berguna untuk teman-teman dan diri saya di masa yang akan datang.

Code:
alter user 'root'@'localhost' identified with mysql_native_password by '';

Dan akhirnya MySQL saya kembali seperti semula. Alhamdulillah.

Code:
$ mysql -uroot -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 26
Server version: 8.0.30-0ubuntu0.20.04.2 (Ubuntu)

Copyright (c) 2000, 2022, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

Print this item