Magyar zászlóMagyar

Task 6 – Nation Assignment CRUD (PHP)

PHP Exam 2024-25-2 12 points total

Project Files

The starter index.php already loads both data files and has the form structure. videos.php provides $videos — an array of video objects, each with ->id, ->title, and ->nation (initially ''). nations.php provides $nations — an array of country name strings.

<?php
require_once "nations.php";
require_once "videos.php";
// ✏️ Add your PHP logic here
?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <title>Task 6.</title>
    <link rel="stylesheet" href="index.css" />
</head>
<body>
    <h1>6. Nations</h1>
    <div id="main">
        <div id="form">
            <form>
                <select name="nation">
                    <?php foreach($nations as $nation): ?>
                        <option value="<?=$nation?>"><?=$nation?></option>
                    <?php endforeach ?>
                </select>
                <select name="id">
                    <?php foreach($videos as $video): ?>
                        <option value="<?=$video->id?>"><?=$video->title?></option>
                    <?php endforeach ?>
                </select>
                <input type="submit">
            </form>
        </div>
        <div id="videos">
            <div id="left">
                <h2>No nation</h2>
                <!-- ✏️ Render unassigned videos here -->
                <div>Joost Klein - Europapa</div>
                <div>Little Big - Uno</div>
            </div>
            <div id="right">
                <h2>Has nation</h2>
                <!-- ✏️ Render assigned videos here -->
                <div><a href="">🚯</a> AWS - Viszlát Nyár | Hungary</div>
                <div><a href="">🚯</a> Baby Lasagna - Rim Tim Tagi Dim | Croatia</div>
            </div>
        </div>
    </div>
</body>
</html>
<?php
$nations = [
  "Albania", "Andorra", "Armenia", "Australia", "Austria",
  "Azerbaijan", "Belgium", "Bosnia and Herzegovina", "Bulgaria",
  "Croatia", "Cyprus", "Czech Republic", "Denmark", "Estonia",
  "Finland", "France", "Georgia", "Germany", "Greece", "Hungary",
  // ... 48 nations total
];
<?php
$videos = [
    (object)[ "id" => "0573ddf4", "title" => "Alexander Rybak - Fairytale",  "nation" => "" ],
    (object)[ "id" => "069687d6", "title" => "Loreen - Euphoria",             "nation" => "" ],
    (object)[ "id" => "1479a2fe", "title" => "JJ - Wasted Love",              "nation" => "" ],
    (object)[ "id" => "31fb4561", "title" => "AWS - Viszlát Nyár",            "nation" => "" ],
    // ... 32 videos total, all nation: ""
];

Key PHP fact: Objects in a PHP array are stored by reference. Modifying $video->nation inside a foreach ($videos as $video) loop modifies the original object in $videos — no array reassignment needed.


Render the two-column layout (no-nation / has-nation)
array_filter()array_values()foreachalternative syntax
3 pts
Requirement

Split $videos into two arrays — videos without a nation and videos with one. Render each group in its own column (#left and #right), replacing the hardcoded placeholder divs.

array_filter($videos, $callback) returns a new array keeping only elements where the callback returns true. It preserves original keys — indices might be [0, 3, 7, ...]. array_values() re-indexes to [0, 1, 2, ...].

The two-column layout mirrors what the starter HTML already has with #left / #right divs. You replace the hardcoded example <div> elements with a foreach loop.

<?php
$noNation  = array_values(array_filter($videos, fn($v) => $v->nation === ''));
$hasNation = array_values(array_filter($videos, fn($v) => $v->nation !== ''));
?>

<!-- In #left: -->
<?php foreach ($noNation as $video): ?>
    <div><?= htmlspecialchars($video->title) ?></div>
<?php endforeach; ?>

<!-- In #right: -->
<?php foreach ($hasNation as $video): ?>
    <div><?= htmlspecialchars($video->title) ?> | <?= htmlspecialchars($video->nation) ?></div>
<?php endforeach; ?>
Assign a nation via POST form
$_POSTforeach by referencebreak
2 pts
Requirement

When the form is submitted (POST request), find the video matching $_POST['id'] and set its nation to $_POST['nation'].

PHP objects are passed by reference automatically. When iterating foreach ($videos as $video), $video is a reference to the same object in $videos — so assigning $video->nation = $nation mutates the original object. No &$video or array reassignment is needed.

The starter form posts two values: name="nation" (from the nations dropdown) and name="id" (from the videos dropdown). Process this block at the top of the file — before rendering — so the page shows the updated state immediately.

break exits the loop after the first match. Since each ID is unique, there is no need to continue scanning.

if ($_POST) {
    $targetId = $_POST['id']     ?? '';
    $nation   = $_POST['nation'] ?? '';

    foreach ($videos as $video) {
        if ($video->id === $targetId) {
            $video->nation = $nation;
            break;
        }
    }
}
Delete (clear) a nation via GET link
$_GETisset()href with query string
3 pts
Requirement

Add a delete link next to each assigned video. When clicked, the link should call the page with ?delete={id}. At the top of the PHP block, handle this by clearing the matched video’s nation.

A plain <a> link triggers a GET request — which is how isset($_GET['delete']) detects the delete action. Using a link (not a form) is fine for a one-step action in exam context; production apps would use a POST form with CSRF protection.

Process GET before POST (and before rendering) so the page reflects the deletion on the same request. The order at the top should be: handle delete → handle assign → split arrays → render.

urlencode($video->id) is technically unnecessary for pure hex IDs, but is good practice whenever building query strings from data values.

// In the PHP block at the top:
if (isset($_GET['delete'])) {
    foreach ($videos as $video) {
        if ($video->id === $_GET['delete']) {
            $video->nation = '';
            break;
        }
    }
}

// In the #right column (inside the foreach loop):
<a href="?delete=<?= urlencode($video->id) ?>">🚯</a>
Nation dropdown populated from $nations
foreach inside selectoption value
2 pts
Requirement

The <select name="nation"> in the assign form must be populated dynamically from the $nations array. The starter already has this — verify it is correct.

The starter already has this foreach loop for the nations dropdown. If it is present and correct in your starter, this subtask requires no additional code — just make sure you have not accidentally broken it.

The value attribute and the visible label are both set to $nation. When the form is submitted, $_POST['nation'] will be the selected country name string.

htmlspecialchars() on both value and text content prevents XSS in case a nation name contains &, <, or ".

<select name="nation">
    <?php foreach ($nations as $nation): ?>
        <option value="<?= htmlspecialchars($nation) ?>">
            <?= htmlspecialchars($nation) ?>
        </option>
    <?php endforeach; ?>
</select>
Sort both lists alphabetically
usort()strcmp()ascending order
2 pts
Requirement

Sort the no-nation list A–Z by video title. Sort the has-nation list A–Z by nation name.

strcmp($a, $b) compares two strings lexicographically and returns negative, zero, or positive — exactly what usort expects. For ascending A–Z, put $a first: strcmp($a->title, $b->title). For descending Z–A, swap the arguments.

Call usort after array_filter (after the split), on the two separate arrays. Sorting the full $videos array would mix no-nation and has-nation videos together.

usort sorts in place — it modifies $noNation and $hasNation directly. No reassignment is needed.

usort($noNation,  fn($a, $b) => strcmp($a->title,  $b->title));
usort($hasNation, fn($a, $b) => strcmp($a->nation, $b->nation));

Complete Solution

<?php
require_once "nations.php";
require_once "videos.php";

// c: handle delete
if (isset($_GET['delete'])) {
    foreach ($videos as $video) {
        if ($video->id === $_GET['delete']) {
            $video->nation = '';
            break;
        }
    }
}

// b: handle assign
if ($_POST) {
    $targetId = $_POST['id']     ?? '';
    $nation   = $_POST['nation'] ?? '';
    foreach ($videos as $video) {
        if ($video->id === $targetId) {
            $video->nation = $nation;
            break;
        }
    }
}

// a + e: split and sort
$noNation  = array_values(array_filter($videos, fn($v) => $v->nation === ''));
$hasNation = array_values(array_filter($videos, fn($v) => $v->nation !== ''));
usort($noNation,  fn($a, $b) => strcmp($a->title,  $b->title));
usort($hasNation, fn($a, $b) => strcmp($a->nation, $b->nation));
?>
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Task 6.</title><link rel="stylesheet" href="index.css"></head>
<body>
    <h1>6. Nations</h1>
    <div id="main">
        <div id="form">
            <form method="post">
                <!-- d: nations dropdown -->
                <select name="nation">
                    <?php foreach ($nations as $nation): ?>
                        <option value="<?= htmlspecialchars($nation) ?>"><?= htmlspecialchars($nation) ?></option>
                    <?php endforeach; ?>
                </select>
                <!-- videos dropdown -->
                <select name="id">
                    <?php foreach ($videos as $video): ?>
                        <option value="<?= $video->id ?>"><?= htmlspecialchars($video->title) ?></option>
                    <?php endforeach; ?>
                </select>
                <input type="submit">
            </form>
        </div>
        <div id="videos">
            <!-- a: left column — no nation -->
            <div id="left">
                <h2>No nation</h2>
                <?php foreach ($noNation as $video): ?>
                    <div><?= htmlspecialchars($video->title) ?></div>
                <?php endforeach; ?>
            </div>
            <!-- a: right column — has nation, with delete link -->
            <div id="right">
                <h2>Has nation</h2>
                <?php foreach ($hasNation as $video): ?>
                    <div>
                        <a href="?delete=<?= urlencode($video->id) ?>">🚯</a>
                        <?= htmlspecialchars($video->title) ?> | <?= htmlspecialchars($video->nation) ?>
                    </div>
                <?php endforeach; ?>
            </div>
        </div>
    </div>
</body>
</html>