Skip to main content

#95 Download all the photos from a specific contest

Posted in ‘NorrCompetition’
This is a public ticket

Everybody will be able to see its contents. Do not include usernames, passwords or any other sensitive information.

Environment Information (available for public)

PHP version
7.4

Latest post by b2z on Wednesday, 20 March 2024 08:37 EET

webquality

Good morning,

I can't find a way to download all the photos from a specific contest.

Did I look wrong?
Is it possible via the front-end?

Thank you so much.

b2z

Dear Juline,

It is not possible. What is the user case for such action?

Kind regards,

Dmitrijs

webquality

I do markets where I sell beer and liquor and I hold photo competitions during these markets.
The winner receives a bottle of liquor at the end of the market.

And at each market I make a photo album on the Facebook page with the photos that were taken during the market.

This is why all my somewhat specific requests ;)

b2z

Well the only way is to download by FTP. All images of the contests are stored under {ncuploads}/photos, where {ncuploads} is the folder that you define in component options.

Kind regards,

Dmitrijs

webquality

ok, i have a solution for this :

I have add a php script on my joomla installation and i have create one direct link by button on my site.


First : only connected user see the button

Second : joomla connected user check for access to the script

 

Is my logic correct?

The script checks which user is connected and will create an archive with only the photos from their competition.
For my use there is only one competition that will be created per user so that's good.

I just have in my treeessence for the future?

Is it possible to transform it into a module or plugin for your component?

 

 

 

<?php

define('_JEXEC', 1);
define('JPATH_BASE', __DIR__);
require_once JPATH_BASE . '/includes/defines.php';
require_once JPATH_BASE . '/includes/framework.php';

// Initialisation
$container = \Joomla\CMS\Factory::getContainer();
$container->alias('session.web', 'session.web.site')
          ->alias('session', 'session.web.site')
          ->alias('JSession', 'session.web.site')
          ->alias(\Joomla\CMS\Session\Session::class, 'session.web.site')
          ->alias(\Joomla\Session\Session::class, 'session.web.site')
          ->alias(\Joomla\Session\SessionInterface::class, 'session.web.site');

$app = $container->get(\Joomla\CMS\Application\SiteApplication::class);
\Joomla\CMS\Factory::$application = $app;

$userInfo = \Joomla\CMS\Factory::getApplication()->getSession()->get('user');

$db = \Joomla\CMS\Factory::getDbo();
$query = $db->getQuery(true);
$query->select($db->quoteName('title'))
      ->from($db->quoteName('#__competition_competitions'))
      ->where($db->quoteName('created_user_id') . ' = ' . $db->quote($userInfo->id));
$db->setQuery($query);

$competitionTitle = $db->loadResult();


/// Chemin du dossier à archiver et création de l'archive
$directoryPath = JPATH_BASE . '/ncuploads/' . $competitionId . '/';
$username = preg_replace("/[^a-zA-Z0-9]+/", "", $userInfo->username); // Utilisez $userInfo pour obtenir le nom d'utilisateur
$archiveName = JPATH_BASE . '/archives_gallery/' . $username . '_' . date('Y-m-d_H-i-s') . '.zip';

if (!\Joomla\CMS\Filesystem\Folder::exists(JPATH_BASE . '/archives_gallery/')) {
    \Joomla\CMS\Filesystem\Folder::create(JPATH_BASE . '/archives_gallery/');
}

$zip = new \ZipArchive();
if ($zip->open($archiveName, \ZipArchive::CREATE) !== TRUE) {
    exit("Impossible de créer l'archive <$archiveName>\n");
}


// Fonction récursive pour ajouter des fichiers au ZIP
function addFilesToZip($dir, $zip) {
    $files = scandir($dir);
    foreach ($files as $file) {
        if ($file == '.' || $file == '..') continue;
        $path = $dir . '/' . $file;
        if (is_dir($path)) {
            addFilesToZip($path, $zip); // Appel récursif sans $baseDir
        } else {
            if (strpos($file, 'big_') === 0) {
                // Ajoute le fichier directement à la racine de l'archive, sans $baseDir
                $zip->addFile($path, basename($file));
            }
        }
    }
}


addFilesToZip($directoryPath, $zip);
$zip->close();

// Préparation au téléchargement de l'archive
header('Content-Type: application/zip');
header('Content-Disposition: attachment; filename="' . basename($archiveName) . '"');
header('Content-Length: ' . filesize($archiveName));
readfile($archiveName);

b2z

Your logic is correct. Probably you can create a module with the button and this code, then put it on the contest page. Another way that may work - create an AJAX plugin that will be executed by click on the button.

My comments for your code is below:

1. As far as I know to get the user you can use:
$userInfo = \Joomla\CMS\Factory::getApplication()->getIdentity();

Then
if ($userInfo->guest) {
    exit('User is not logged in');
}

2. I think you have a mistake here:
$query->select($db->quoteName('title'))

It should be:
$query->select($db->quoteName('id'))

And then instead of
$competitionTitle = $db->loadResult();
should be
$competitionId = $db->loadResult();

webquality

Like this ?
I have a lot of questions because I'm learning at the same time ;)

 

<?php

define('_JEXEC', 1);
define('JPATH_BASE', __DIR__);
require_once JPATH_BASE . '/includes/defines.php';
require_once JPATH_BASE . '/includes/framework.php';

// Initialisation
$container = \Joomla\CMS\Factory::getContainer();
$container->alias('session.web', 'session.web.site')
          ->alias('session', 'session.web.site')
          ->alias('JSession', 'session.web.site')
          ->alias(\Joomla\CMS\Session\Session::class, 'session.web.site')
          ->alias(\Joomla\Session\Session::class, 'session.web.site')
          ->alias(\Joomla\Session\SessionInterface::class, 'session.web.site');

$app = $container->get(\Joomla\CMS\Application\SiteApplication::class);
\Joomla\CMS\Factory::$application = $app;

// Récupération des informations de l'utilisateur et vérification de la connexion
$userInfo = \Joomla\CMS\Factory::getApplication()->getIdentity();
if ($userInfo->guest) {
    exit('User is not logged in');
}


// Ajustement de la requête SQL pour récupérer l'ID de la compétition
$db = \Joomla\CMS\Factory::getDbo();
$query = $db->getQuery(true);
$query->select($db->quoteName('id'))
      ->from($db->quoteName('#__competition_competitions'))
      ->where($db->quoteName('created_user_id') . ' = ' . $db->quote($userInfo->id));
$db->setQuery($query);

$competitionId = $db->loadResult(); // Utilisation de l'ID pour les opérations suivantes



/// Chemin du dossier à archiver et création de l'archive
$directoryPath = JPATH_BASE . '/ncuploads/' . $competitionId . '/';
$username = preg_replace("/[^a-zA-Z0-9]+/", "", $userInfo->username); // Utilisez $userInfo pour obtenir le nom d'utilisateur
$archiveName = JPATH_BASE . '/archives_gallery/' . $username . '_' . date('Y-m-d_H-i-s') . '.zip';

if (!\Joomla\CMS\Filesystem\Folder::exists(JPATH_BASE . '/archives_gallery/')) {
    \Joomla\CMS\Filesystem\Folder::create(JPATH_BASE . '/archives_gallery/');
}

$zip = new \ZipArchive();
if ($zip->open($archiveName, \ZipArchive::CREATE) !== TRUE) {
    exit("Impossible de créer l'archive <$archiveName>\n");
}


// Fonction récursive pour ajouter des fichiers au ZIP
function addFilesToZip($dir, $zip) {
    $files = scandir($dir);
    foreach ($files as $file) {
        if ($file == '.' || $file == '..') continue;
        $path = $dir . '/' . $file;
        if (is_dir($path)) {
            addFilesToZip($path, $zip); // Appel récursif sans $baseDir
        } else {
            if (strpos($file, 'big_') === 0) {
                // Ajoute le fichier directement à la racine de l'archive, sans $baseDir
                $zip->addFile($path, basename($file));
            }
        }
    }
}


addFilesToZip($directoryPath, $zip);
$zip->close();

// Préparation au téléchargement de l'archive
header('Content-Type: application/zip');
header('Content-Disposition: attachment; filename="' . basename($archiveName) . '"');
header('Content-Length: ' . filesize($archiveName));
readfile($archiveName);

b2z

Seems like correct. Do you have a situtation when user does not have a competition? In this case the query will fail.

Kind regards,

Dmitrijs

webquality

Well seen ;)

But in my case each user will have their competition necessarily created in advance.

On the other hand, I find it quite strange that for a photo competition component that there is not in the basic code the possibility for users to download their photos as well as for the competition organizers to download their respective gallery in one click.

Either a possibility of downloading by selecting the photos one by one or an upload destination folder by competition.

Maybe an idea for the next update of the component to make it native.

In any case, I'm making quite a bit of progress on the configurations and changes that I need to put in place so that it does exactly what I want hehe

Many thanks for your valuable help.

b2z

Thank you, noted. You have quite a specific request as before NorrCompetition users did not ask for such feature :)

Kind regards,

Dmitrijs

Support information

Support hours: You can get our help: Monday - Friday / 09:00 to 17:00 (GMT+3), but not limited. Our staff is pleased to provide Premium support to every paid subscriber asap, but sometimes you should be ready to wait for our reply for up to 3 days.


Our time: / Your time:

Support policy: We would like to kindly inform you that when using our support you have already agreed to the Support Policy which is part of our Terms of Service. We also ask you to remove temporary credentials at your site after the problem is resolved. Thank you.

Support of free extensions is not provided on this forum. Please submit your questions or report issues via Github tracker. See link on the product page.