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.
Everybody will be able to see its contents. Do not include usernames, passwords or any other sensitive information.
Latest post by b2z on Wednesday, 20 March 2024 08:37 EET
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.
Dear Juline,
It is not possible. What is the user case for such action?
Kind regards,
Dmitrijs
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 ;)
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
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);
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();
Thenif ($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();
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);
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
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.
Thank you, noted. You have quite a specific request as before NorrCompetition users did not ask for such feature :)
Kind regards,
Dmitrijs