• Welcome to the Chevereto user community!

    Here users from all over the world gather around to learn the latest about Chevereto and contribute with ideas to improve the software.

    Please keep in mind:

    • This community is user driven. Be polite with other users.
    • Is required to purchase a Chevereto license to participate in this community (doesn't apply to Pre-sales).
    • Purchase a Pro Subscription to get access to active software support and faster ticket response times.

Randomizer Code - Turn any album into a randomizer

ashkir

👽 Chevereto Freak
Shutting down my image host. The most popular feature was my randomizer. I thought I'd share the code so you can add it to your site! Please let me know if you decide to use and and what website! My users are looking for a new home (10k+).

Please note this is for v3. This was set up for htaccess/apache servers. If you use nginx please modify it for your server. I am too busy at this time and cannot provide support.

Step one:
Create a subdomain such as
random.yourhost.com

The PHP code. Save this in a file called i.php
PHP:
$servername = "localhost";
$username = "myusername";
$password = "mypassword";
$dbname = "mydatabase";
$id = intval($_GET['id']);


// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
  die("Connection failed: " . $conn->connect_error);
}
$sql = "SELECT CONCAT('https://cdn.yourhost.host/',`image_name`, '.', `image_extension`) AS random_image FROM `chv_images` WHERE `image_album_id` = ".$id." ORDER BY RAND() LIMIT 1";
$result = $conn->query($sql);

if ($result->num_rows > 0) {
  // output data of each row
  while($row = $result->fetch_assoc()) {
  $ranURL = $row["random_image"];
header ('Location: '.$ranURL);
  }
} else {
  echo "doesnt exist";
}
$conn->close();

Go to your Chevereto Themes and in the overrides for views/album.php (located in app/themes/Peafowl) look for the share snippet and add the following:
PHP:
<a class="btn blue" data-modal="simple" data-target="modal-random"><span class="icon fas fa-random"></span><span class="btn-text phone-hide">Randomizer</span></a>
                        <?php G\Render\include_theme_file('snippets/modal_random'); ?>

Go to overrides/snippets and create a new file called modal_random.php and use this code
PHP:
<?php if(!defined('access') or !access) die('This file cannot be directly accessed.'); ?> <?php $share_modal = function_exists('get_share_modal') ? get_share_modal() : G\get_global("share_modal"); ?> <div id="modal-random" class="hidden">    <span class="modal-box-title">Randomizer</span>    <p class="highlight margin-bottom-20 font-size-small text-align-center<?php if(is_null($share_modal["privacy"]) || $share_modal["privacy"] == "public") echo " soft-hidden"; ?>" data-content="privacy-private"><?php echo $share_modal['privacy_notes']; ?></p> Below you can grab your randomizer link! All album images in this album will be in the randomizer. You can add or remove images from the album at any time to effect the randomizer.    <div class="c8 phablet-c1">        <div class="input-label margin-bottom-0">            <label for="modal-share-url"><?php _se('Link'); ?></label>            <input type="text" name="modal-random-url" id="modal-random-url" class="text-input" value="https://random.yourhost.com/<?php $RanAlbumID = get_album()['id']; echo $RanAlbumID; ?>.gif" data-focus="select-all">        </div>    </div> </div>

Last part is your .htaccess

RewriteEngine on
RewriteRule ^(.+)\.gif$ https://random.yourhost.com/i.php?id=$1 [R=301,L]
 
Last edited:
I would also be interested in knowing if anyone has gotten this to work on V4 ^-^ And if they would mind providing a walk-through.
 
Here's V4 version, it has the following improves:
  • Uses native methods (no direct db connection)
  • Randomizer button matches default style
  • Adds a copy button to randomizer modal
  • Uses encoded IDs (not integer ids)
My version works at at /randomizer/id.gif because Nick's works on root, which causes that every gif embed loads the server which could result in higher server CPU load. My version doesn't have this problem as it works only for embeds at /randomizer folder.

app/legacy/routes/overrides/i.php

PHP:
<?php

/*
 * This file is part of Chevereto.
 *
 * (c) Rodolfo Berrios <rodolfo@chevereto.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

use Chevereto\Legacy\Classes\DB;
use Chevereto\Legacy\Classes\Image;
use function Chevereto\Legacy\decodeID;
use Chevereto\Legacy\G\Handler;
use function Chevereto\Vars\get;

return function (Handler $handler) {
    $albumId = get()['album'] ?? null;
    if ($albumId === null) {
        return $handler->issueError(404);
    }
    $albumId = decodeID($albumId);
    $table = DB::getTable('images');
    $fetch = DB::queryFetchSingle(
        <<<SQL
        SELECT `image_id` FROM $table WHERE `image_album_id` = $albumId ORDER BY RAND() LIMIT 1;
        SQL
    );
    if (!$fetch) {
        return $handler->issueError(404);
    }
    $imageId = $fetch['image_id'];
    $image = Image::getSingle(
        id: $imageId,
        pretty: true,
    );
    header('Location: ' . $image['url']);
    die();
};

content/legacy/themes/Peafowl/overrides/snippets/modal_random.php

PHP:
<?php
use function Chevereto\Legacy\G\get_public_url;
use Chevereto\Legacy\G\Handler;
if (!defined('ACCESS') || !ACCESS) {
    die('This file cannot be directly accessed.');
}
?>
<div id="modal-random" class="hidden">
    <span class="modal-box-title">Randomizer</span>
    <p>All images in this album will be in the randomizer. You can add or remove images from the album at any time to effect the randomizer.</p>
    <div>
        <div class="input-label margin-bottom-0">
            <label for="modal-share-url"><?php _se('Link'); ?></label>
            <div class="position-relative">
                <input type="text" name="modal-random-url" id="modal-random-url" class="text-input" value="<?php echo get_public_url('randomizer/' . Handler::var('album')['id_encoded']) . '.gif'; ?>" data-focus="select-all">
                <button type="button" class="input-action" data-action="copy" data-action-target="#modal-random-url"><i class="far fa-copy"></i> <?php _se('copy'); ?></button>
            </div>
        </div>
    </div>
</div>

content/legacy/themes/Peafowl/overrides/views/album.php

PHP:
<?php
use function Chevereto\Legacy\arr_printer;
use function Chevereto\Legacy\G\get_base_url;
use function Chevereto\Legacy\G\get_global;
use Chevereto\Legacy\G\Handler;
use function Chevereto\Legacy\G\include_theme_file;
use function Chevereto\Legacy\G\include_theme_footer;
use function Chevereto\Legacy\G\include_theme_header;
use function Chevereto\Legacy\getSetting;
use function Chevereto\Legacy\isShowEmbedContent;
use function Chevereto\Legacy\show_banner;
use function Chevereto\Legacy\time_elapsed_string;
use function Chevereto\Vars\request;
// @phpstan-ignore-next-line
if (!defined('ACCESS') || !ACCESS) {
    die('This file cannot be directly accessed.');
} ?>
<?php include_theme_header(); ?>
<div class="content-width">
    <?php show_banner('album_before_header', Handler::var('listing')->sfw()); ?>
    <div class="header header-content margin-bottom-10 margin-top-10">
        <div class="header-content-left">
            <div class="header-content-breadcrum">
            <?php
                if (Handler::var('album')['user']['id']) {
                    include_theme_file("snippets/breadcrum_owner_card");
                } else {
                    ?>
                    <div class="breadcrum-item">
                        <div class="user-image default-user-image"><span class="icon fas fa-user-circle"></span></div>
                    </div>
                <?php
                }
                ?>
                <div class="breadcrum-item" data-contains="cta-album">
                <?php echo Handler::var('album')['cta_html']; ?>
                </div>
            </div>
        </div>
        <div class="header-content-right breaks-ui">
        <?php
                if (Handler::cond('owner') || Handler::cond('content_manager')) {
                    ?>
                    <a data-action="edit" title="<?php _se('Edit'); ?> (E)" class="btn btn-small default" data-modal="edit"><span class="icon fas fa-edit"></span></a>
                    <a data-action="sub-album" title="<?php _se('Sub album'); ?> (J)" class="btn btn-small default" data-modal="edit" data-target="new-sub-album"><span class="icon fas fa-level-down-alt"></span></a>
                    <?php
                    if (Handler::cond('allowed_to_delete_content')) {
                        ?>
                            <a data-action="delete" title="<?php _se('Delete'); ?> (Del)" class="btn btn-small default" data-confirm="<?php _se("Do you really want to delete this %a and all of its %i?", ['%a' => _n('album', 'albums', 1), '%i' => _n('image', 'images', 20)]); ?> <?php _se("This can't be undone."); ?>" data-submit-fn="CHV.fn.submit_resource_delete" data-ajax-deferred="CHV.fn.complete_resource_delete" data-ajax-url="<?php echo get_base_url("json"); ?>"><span class="icon fas fa-trash-alt"></span></a>
                    <?php
                    } ?>
                <?php
                }
                ?>
        <?php
            if (Handler::cond('owner')) {
                if (getSetting('upload_gui') == 'js' && getSetting('homepage_style') !== 'route_upload') {
                    $createAlbumTag = 'button';
                    $createAlbumAttr = 'data-trigger="anywhere-upload-input" data-action="upload-to-album" title="' . _s('Upload to album') . ' (P)"';
                } else {
                    $createAlbumTag = 'a';
                    $createAlbumAttr = 'href="' . get_base_url(sprintf('upload/?toAlbum=%s', Handler::var('album')['id_encoded'])) . '"';
                } ?>
                <<?php echo $createAlbumTag; ?> class="btn btn-small default" <?php echo $createAlbumAttr; ?>><span class="btn-icon fas fa-cloud-upload-alt"></span></<?php echo $createAlbumTag; ?>>
            <?php
            }
            ?>
            <?php
            if (getSetting('theme_show_social_share')) {
                ?>
                <a class="btn btn-small default" data-action="share" title="<?php _se('Share'); ?> (S)"><span class="btn-icon fas fa-share-alt"></span></a>
            <?php
            }
            ?>
            <a class="btn btn-small default" title="Randomizer" data-modal="simple" data-target="modal-random"><span class="icon fas fa-random"></span></a>
                        <?php include_theme_file('snippets/modal_random'); ?>
            <?php
            if (getSetting('enable_likes')) {
                ?>
                <a title="<?php _se('Like'); ?> (L)" class="btn-like" data-type="album" data-id="<?php echo Handler::var('album')['id_encoded']; ?>" data-liked="<?php echo (int) (Handler::var('album')['liked'] ?? '0'); ?>">
                    <span data-action="like" class="btn btn-small default btn-liked" rel="tooltip" title="<?php _se("You like this"); ?>"><span class="btn-icon fas fa-heart"></span><span class="btn-text" data-text="likes-count"><?php echo Handler::var('album')['likes']; ?></span></span>
                    <span class="btn btn-small default btn-unliked" data-action="like"><span class="btn-icon far fa-heart"></span><span class="btn-text" data-text="likes-count"><?php echo Handler::var('album')['likes']; ?></span></span>
                </a>
            <?php
            }
            ?>
        </div>
    </div>
    <div class="header margin-bottom-10">
        <h1 class="header-title phone-float-none viewer-title">
            <a data-text="album-name" href="<?php echo Handler::var('album')["url"]; ?>"><?php echo Handler::var('album')["name_html"]; ?></a>
        </h1>
    </div>
    <div class="description-meta margin-bottom-10 overflow-auto">
        <div class="header-content-left phone-margin-bottom-20">
            <span class="icon far fa-eye-slash <?php if (Handler::var('album')["privacy"] == "public") {
                echo "soft-hidden";
            } ?>" data-content="privacy-private" title="<?php _se('This content is private'); ?>" rel="tooltip"></span>
           <span class="far fa-images"></span> <span data-text="image-count"><?php echo Handler::var('album')["image_count"]; ?></span> <span data-text="image-label" data-label-single="<?php _ne('image', 'images', 1); ?>" data-label-plural="<?php _ne('image', 'images', 2); ?>"><?php _ne('image', 'images', Handler::var('album')['image_count']); ?></span> — <span class="far fa-clock"></span> <?php echo '<span title="' . Handler::var('album')['date_fixed_peer'] . '">' . time_elapsed_string(Handler::var('album')['date_gmt']) . '</span>'; ?> — <span class="far fa-views"></span><?php echo Handler::var('album')['views']; ?> <?php echo Handler::var('album')['views_label']; ?>
        </div>
    </div>
    <?php show_banner('album_after_header', Handler::var('listing')->sfw()); ?>
    <div class="description-meta margin-bottom-10" data-text="album-description"><?php echo nl2br(trim(Handler::var('album_safe_html')['description'] ?? '')); ?></div>
</div>
<div class="top-sub-bar follow-scroll margin-bottom-5 margin-top-5">
    <div class="content-width">
        <div class="header header-tabs no-select">
            <?php include_theme_file("snippets/tabs"); ?>
            <?php
            if (Handler::cond('owner') || Handler::cond('content_manager')) {
                include_theme_file("snippets/user_items_editor"); ?>
                <div class="header-content-right">
                    <?php include_theme_file("snippets/listing_tools_editor"); ?>
                </div>
            <?php
            }
            ?>
        </div>
    </div>
</div>
<div class="content-width">
    <div id="content-listing-tabs" class="tabbed-listing">
        <div id="tabbed-content-group">
            <?php
            include_theme_file("snippets/listing");
            ?>
            <?php if (isShowEmbedContent()) {
                ?>
                <div id="tab-embeds" class="tabbed-content padding-10">
                        <div class="content-listing-loading"></div>
                        <div id="embed-codes" class="input-label margin-bottom-0 margin-top-0 soft-hidden">
                            <label for="album-embed-toggle"><?php _se('Embed codes'); ?></label>
                            <div class="c8 margin-bottom-10">
                                <select name="album-embed-toggle" id="album-embed-toggle" class="text-input" data-combo="album-embed-toggle-combo">
                                    <?php
                                    foreach (get_global('embed_share_tpl') as $key => $value) {
                                        echo '<optgroup label="' . $value['label'] . '">' . "\n";
                                        foreach ($value['options'] as $k => $v) {
                                            echo '  <option value="' . $k . '" data-size="' . $v["size"] . '">' . $v["label"] . '</option>' . "\n";
                                        }
                                        echo '</optgroup>';
                                    } ?>
                                </select>
                            </div>
                            <div id="album-embed-toggle-combo" class="position-relative">
                                <?php
                                $i = 0;
                foreach (get_global('embed_share_tpl') as $key => $value) {
                    foreach ($value['options'] as $k => $v) {
                        echo '<div data-combo-value="' . $k . '" class="switch-combo' . ($i > 0 ? " soft-hidden" : "") . '">
                                        <textarea id="album-embed-code-' . $i . '" class="r8 resize-vertical" name="' . $k . '" data-size="' . $v["size"] . '" data-focus="select-all"></textarea>
                                        <button type="button" class="input-action" data-action="copy" data-action-target="#album-embed-code-' . $i . '"><i class="far fa-copy"></i> ' . _s('copy') . '</button>
                                    </div>' . "\n";
                        $i++;
                    }
                } ?>
                            </div>
                        </div>
                </div>
            <?php
            } ?>
            <?php
            if (Handler::cond('admin')) {
                ?>
                <div id="tab-info" class="tabbed-content padding-10<?php if (Handler::var('current_tab') === 'tab-info') {
                    echo ' visible';
                } ?>">
                    <?php echo arr_printer(Handler::var('album_safe_html'), '<li><div class="c4 display-table-cell padding-right-10 font-weight-bold">%K</div> <div class="display-table-cell">%V</div></li>', ['<ul class="tabbed-content-list table-li">', '</ul>']); ?>
                </div>
            <?php
            }
            ?>
        </div>
    </div>
</div>
<?php if (Handler::cond('content_manager')) { ?>
<script>
    $(function() {
        CHV.fn.ctaForm.enable = <?php echo Handler::var('album')['cta_enable']; ?>;
        CHV.fn.ctaForm.array = <?php echo Handler::var('album')['cta']; ?>;
    });
</script>
<?php
            } ?>
<?php
if (Handler::cond('content_manager') || Handler::cond('owner')) {
                include_theme_file('snippets/modal_edit_album');
                include_theme_file('snippets/modal_create_sub_album');
            }
?>
<?php if (Handler::cond('content_manager') and isset(request()["deleted"])) { ?>
    <script>
        $(function() {
            PF.fn.growl.expirable("<?php _se('The content has been deleted.'); ?>");
        });
    </script>
<?php } ?>
<?php if (Handler::var('current_tab') === 'tab-embeds') { ?>
    <script>
        $(function () {
            CHV.fn.album.showEmbedCodes();
        })
    </script>
<?php } ?>
<?php include_theme_footer(); ?>

.htaccess

You will require to use RewriteRule randomizer/(.+)\.gif$ i/?album=$1 [R=301,L] at your server rewrite.

Apache config:
ServerSignature Off
Options -Indexes
Options -MultiViews
# CORS header (avoids font rendering issues)(replace dev\.local with your domain\.com)
# SetEnvIf Origin ^(https?://.+\.dev\.local(?::\d{1,5})?)$   CORS_ALLOW_ORIGIN=$1
# Header append Access-Control-Allow-Origin  %{CORS_ALLOW_ORIGIN}e   env=CORS_ALLOW_ORIGIN
# Header merge  Vary "Origin"
<FilesMatch "\.htaccess|LICENSE">
    Require all denied
</FilesMatch>
<IfModule mod_rewrite.c>
    RewriteEngine On
    # If you have problems with the rewrite rules remove the "#" from the following RewriteBase line
    # You will also have to change the path to reflect the path to your Chevereto installation
    # If you are using mod alias is likely that you will need this.
    #RewriteBase /

    # Image not found replacement
    RewriteCond %{REQUEST_FILENAME} !-f
    #RewriteRule images/.+\.(gif|jpe?g|a?png|bmp|webp) content/images/system/default/404.gif [NC,L]
    RewriteRule images/.+\.(gif|jpe?g|png|bmp|webp) - [NC,L,R=404]

    RewriteRule randomizer/(.+)\.gif$ i/?album=$1 [R=301,L]

    # PHP front controller
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . index.php [L]

    # Single PHP-entrypoint
    RewriteCond %{THE_REQUEST} ^.+?\ [^?]+\.php[?\ ] [NC]
    RewriteRule \.php$ - [NC,L,F,R=404]
</IfModule>
 
Last edited:
Using Rodolfo's v4 code (and the latest version of Chevereto), I have all pieces of code in all the places they need to be. I'm even populating a Randomizer button with the correct link to my album. However, posting it to my forum doesn't populate any images. Posting the direct link to my forum for any image inside of the album works, just not the Randomizer GIF link itself. Is there any other setting I should be changing? Has anyone else run into this issue?
 
Thank you @Rodolfo for this. I’m so glad someone updated it. I remembered years ago when I was asking if this was possible a lot of people on this forum laughed at me. Didn’t see the purpose erc. But your PM with some database hints let me get it working for my user base.

Now I’m happy others can use it. This was by far the most popular feature on nickpic and now I’m glad no matter where my community goes they have a chance to have this feature.
 
Back
Top