Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ajax & Session Variables? Worksafe Filter (selective image hiding)

I'm building a photography portfolio. Some of my images have nudity, so I want to hide those by default until the user clicks a "Toggle Worksafe Mode" button.

I can do it with a standard form post (and sessions), but that causes "confirm form resubmission" errors when the user backs or reloads. I'm trying to figure out an AJAX post instead to avoid that.

UPDATE: This is the working code. Please note that this does NOT work with the "slim" jQuery distro; that's one of the main reasons I was having trouble.

Image Index Page:

<?php
    session_start();
    if (!isset($_SESSION['Worksafe_Mode'] {
        $_SESSION['Worksafe_Mode'] = 1;
    }
?>
<!-- other page content -->
<script src="scripts/jquery-3.2.1.min.js"></script>
<!-- other page content -->
<button type="button" id="Worksafe_Button" name="Worksafe_Button">
    Toggle Worksafe Mode
</button>
<script>
    $('#Worksafe_Button').click(function() {
        $.post("worksafe_mode_toggle.php")
            .done(function(data) {
                window.location.href = window.location.href;
        });
    });
</script>
<!-- other page content -->
<?php
$Connection = Connect();
$query = mysqli_query($Connection, 'SELECT uri, name, nsfw FROM images ORDER BY uri');

while($row = mysqli_fetch_assoc($image)) {
    if ($_SESSION['Worksafe_Mode'] == 1 && $row['nsfw'] == 1) {
        echo 'If you are over 18, toggle Worksafe Mode to view this image';
    }
    else {
        echo '<img alt="'.$row['title'].'" src="../'.$row['uri'].'/s.jpg" srcset="../'.$row['uri'].'/m.jpg 2x">';
    }
}
?>

worksafe_mode_script:

session_start();
if (isset($_SESSION['Worksafe_Mode'])) {
    if ($_SESSION['Worksafe_Mode'] == 1) {
        $_SESSION['Worksafe_Mode'] = 0;
    }
    else {
        $_SESSION['Worksafe_Mode'] = 1;
    }
}
like image 355
Lee Saxon Avatar asked Jun 28 '17 15:06

Lee Saxon


2 Answers

I think ajax is a good approach in your case.

I might do something like display a page of SFW images as the default, along with the toggle button.

When they click the button it triggers an ajax request to the back-end that sets/un-sets the session value in toggleWorksafe.php. Finally it triggers a page refresh.

During the page refresh the PHP code checks whether the session variable is set and shows either the filtered or unfiltered set of images, and changes the button's text to match.

To implement:

Include jQuery in the <head> section (jQuery simplifies the ajax call):

<!DOCTYPE html>
<html>

<head>
  <script src="https://code.jquery.com/jquery-3.2.1.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script>
</head>

<body>
  <?php
    session_start();
    if (!isset($_SESSION['Worksafe_Mode'])) {
        $_SESSION['Worksafe_Mode'] = 'yes';
    }
  ?>

  <button id="workSafe" type="button" name="Worksafe_Toggle_Button">
  <?php 
    if ($_SESSION['Worksafe_Mode'] == 'no') {
      echo 'Hide NSFW images';
    }
    else {
      echo 'Include NSFW images';
    }
  ?>
  </button>

  <!-- display safe images by default -->
  <?php 
    if ($_SESSION['Worksafe_Mode'] == 'no') {
      echo '<br/><br/>Showing NSFW images';
    }
    else {
      echo '<br/><br/>Showing safe images only';
    }
  ?>

  <!-- any other page content here -->

  <script>
    $('#workSafe').click(function() {

      // ajax request to page toggling session value
      $.post("/toggleWorksafe.php")
        .done(function(data) {
          window.location.href = window.location.href; // trigger a page refresh
        });
    });
  </script>
</body>

</html>

toggleWorksafe.php:

<?php 
    session_start();
    if (isset($_SESSION['Worksafe_Mode'])) {
        if ($_SESSION['Worksafe_Mode'] == 'yes') {
            $_SESSION['Worksafe_Mode'] = 'no';
        }
        else {
            $_SESSION['Worksafe_Mode'] = 'yes';
        }
    }
    else {
        $_SESSION['Worksafe_Mode'] = 'yes';
    }
?>
like image 86
K Scandrett Avatar answered Oct 06 '22 22:10

K Scandrett


there are a couple of ways to do this and it related to how you hide or load you images.

1. simple method

if you don't care about the user's age, and just need to toggle, then you can do it with just a js variable, a cookie, and two version of link. with this, you don't hide images, but loads them. the filtering is done in the server, where you can use database query or a simple folder separation. for example:

var nsfw = read_cookie('nsfw', false); // not an actual js function, search for how to read cookie in js --- read cookie value, default to false

function loadImage(nsfw){
    if (nsfw){
        $.get('nsfw-image-list-url', function(resp){
            // the url should return a json with list of image urls
            var list = resp;  // jQuery automatically parse json with the right MIME
            list.forEach(function(val){
                // insert image to page
                $('#container').append('<img src="' + val + '/>');
            });
        });
    } else {
        $.get('sfw-image-list-url', function(resp){
            // the url should return a json with list of image urls
            var list = resp;  // jQuery automatically parse json with the right MIME
            list.forEach(function(val){
                // insert image to page
                $('#container').append('<img src="' + val + '/>');
            });
        });
    }
}

and in you button click event:

nsfw = !nsfw;
// clear the image first if needed
$('#container').empty();
loadImage(nsfw);

2. another simple method, but not as simple as the #1

you can also do it with only one link that returns a list of images with the type of it, such as nsfw or other things.

note: this method still uses cookie

for example the returned list is like this:

[
    {"url": "some-image-1.jpg", "nsfw": "true"}, 
    {"url": "some-image-2.jpg", "nsfw": "false"}, 
    {"url": "some-image-3.jpg", "nsfw": "true"}, 
    {"url": "some-image-4.jpg", "nsfw": "false"}, 
    {"url": "some-image-5.jpg", "nsfw": "false"}, 
    {"url": "some-image-6.jpg", "nsfw": "true"}
]

then you just render it when the conditions are met.

function renderImage(nsfw){
    $.get('image-list-url', function(resp){
        list.forEach(function(val, key){
            if (nsfw || !val.nsfw){
                $('#container').append('<img src="' + val.url + '/>');
            }
        });
    });
}

and many other methods that are too long to explain, such as using Angular, React, or Vue

still uses cookie for between reloads or backs, and does not regard user's age.

as for the session based approach, you only need that if you need to verify your users age

that is if you have a membership functionality with DOB (date of birth) data in your site, if so, you can use @KScandrett 's answer

like image 2
am05mhz Avatar answered Oct 06 '22 20:10

am05mhz