Source Code for /public/appendix-samples/fruits-and-filters-retaining-selection.php

<?php
/**
 * Returns a sorted array of all of the fruit images in the
 * img/fruit directory.
 */
function get_fruits() {
  // Get a sorted list of fruits like we've done before:
  $jpgs = glob('../img/fruit/*.jpg');
  $webps = glob('../img/fruit/*.webp');
  $files = array_merge( $jpgs, $webps );
  sort( $files );
  // Return the list to whichever code called get_fruits()
  return $files;
}

/**
 * Returns an array of CSS filters that can be applied to an
 * image.
 */
function get_filters() {
  return [
    'filter: grayscale(100%)',
    'filter: blur(2px)',
    'filter: brightness(1.5)',
    'filter: contrast(1.5)',
    'filter: hue-rotate(90deg)',
    'filter: invert(1)',
    'filter: sepia(1)',
    'transform: rotateZ(90deg);',
    'transform: skewX(-15deg);',
  ];
}

/**
 * Returns true if the user provided a fruit_id and filter_id.
 * Returns false otherwise.
 */
function user_requested_a_fruit_and_filter() {
  // If they haven't provided a fruit_id or filter_id, false:
  if( ! isset( $_POST['fruit_id'] ) ) return false;
  if( ! isset( $_POST['filter_id'] ) ) return false;
  // Othewise, true!
  return true;
}

/**
 * Shows the requested fruit with the applied CSS filter.
 */
function show_a_filtered_fruit() {
  // Note that we don't ask the user to send us the filename
  // but the NUMBER of the fruit (and filter), in its list.
  // This is a strong validation step - the user can't inject
  // anything we didn't expect them to!
  $fruit_id = intval( $_POST['fruit_id'] );
  $filter_id = intval( $_POST['filter_id'] );
  $fruit = get_fruits()[ $fruit_id ];
  $filter = get_filters()[ $filter_id ];

  // Output the fruit image with the filter applied:
  ?>
  <img src="<?php echo $fruit; ?>"
     width="200"
    height="200"
     style="border: 1px solid black; <?php echo $filter; ?>;">
  <?php
}
?>

<h1>Fruity Filters</h1>

<?php if( user_requested_a_fruit_and_filter() ) { ?>
  <h2>
    Here's your filtered fruit:
  </p>
  <?php show_a_filtered_fruit(); ?>
<?php } ?>

<h2>
  <?php if( user_requested_a_fruit_and_filter() ) { ?>
    Filter another fruit!
  <?php } else { ?>
    Filter a fruit!
  <?php } ?>
</h2>
<form method="post" action="fruits-and-filters-retaining-selection.php">
  <p>
    <label for="fruit">Fruit:</label>
    <select id="fruit" name="fruit_id">
      <?php foreach( get_fruits() as $id => $fruit ) { ?>
        <option
          <?php if( isset( $_POST['fruit_id'] ) && intval( $_POST['fruit_id'] ) === $id ) echo 'selected'; ?>
          value="<?php echo $id; ?>"
        >
          <?php echo basename( $fruit ); ?>
        </option>
      <?php } ?>
    </select>
  </p>

  <p>
    <label for="filter">Filter:</label>
    <select id="filter" name="filter_id">
      <?php foreach( get_filters() as $id => $filter ) { ?>
        <option
          <?php if( isset( $_POST['filter_id'] ) && intval( $_POST['filter_id'] ) === $id ) echo 'selected'; ?>
          value="<?php echo $id; ?>"
        >
          <?php echo $filter; ?>
        </option>
      <?php } ?>
    </select>
  </p>

  <button type="submit">Submit</button>
</form>

<p>
  <a href="/source-viewer.php?file=public/appendix-samples/fruits-and-filters-retaining-selection.php">View source code for this page</a>
</p>