📝 VTK Foto Voting system
My photo club needed a system to collect votes from referees in photo competitions. Previusly there was a heavy task to handle names of all images and count all votes in different spreadsheets, this system solves the issue and in addition gives the possibility to gather votes remotely from judges and publish results of the competition when done. The system is used by the club in the "VTK Foto Tävlingsportal" (note Swedish only).
VTK Photo Competition System v8.2
A resource-efficient, secure and mobile-friendly system designed for digital judging of photo competitions. The system is built on a modern file-based architecture, which means it works quickly and stably without the need for external databases.
Core Logic & Stability
The system design is optimized for multi-user environments . To ensure data security during simultaneous voting, strict file locking is used. This prevents data corruption if multiple judges submit their scores at exactly the same time.
Functional Components
1. Referee portal
Voting interface with real-time validation. Includes help texts, progress status meters, and a weighted scoring system adapted for different competition types.
2. Performance engine
Calculates weighted averages and handles automatic tie-breakers based on total raw scores. Also allows for compilation of referee comments.
3. Administration
Central management of competitions, competition status (draft/published) and configuration of image categories. Also handles resetting and management of image archives.
4. Storage warehouse
All data is stored in structured text and JSON files. This allows for easy backup by only copying file directories, and provides extremely short loading times.
Technical Specifications
- Logic: PHP-based engine with a focus on security and high performance.
- Design: CSS3 with Flexbox/Grid layout and optimization for printing in A4 format.
- Weighted Judging: The system supports dynamic weights for criteria such as Idea, Composition and Technique.
- Security: Built-in protection against malware through strict sanitization of all entered data and session control for logged-in users.
Documentation: Image Contest Module (v2.0)
Last updated: 2026-02-21
1. File Structure & System Architecture
| File name | Purpose and Function |
|---|---|
bild-judge.php |
Main interface for referees. Includes session validation that clears old sessions without names, real-time saving of voice data, and a progress bar for overview. |
bild-adm-portal.php |
Secretariat control panel. Shows competition status and how many images each judge has marked as complete. |
bild-adm-results.php |
Result control. Calculates average score (weighted) and shows ranking before publication. |
bild-admin-vote-editor.php |
Admin editor. Allows manual correction of votes for specific judges. |
bild-public-results.php |
Final result. Public page activated upon status published. Handles weighting and tie-breakers. |
2. Logic for Points & Sorting
- Weighting: The categories Idea, Composition, Technique and Originality can be given different weights. The system multiplies the judge's score by each weight before calculating the average.
- Tie-breaker (Knockout rule): If two entries have identical average score (weighted), the Total Raw Score(I+K+T+O) to distinguish them. The contribution with the highest total is placed at the top.
- Security: If a user is logged in via another module but lacks
judge_name, the system forces a new login to ensure data integrity.
3. Technical configuration: registry.json
For the weights to work in the calculations, the competition must be defined with a weights-object. Here is an example of a correct configuration:
{
"tavling_id_1": {
"name": "Monthly competition February",
"folder": "feb_2026",
"status": "active",
"weights": {
"I": 3,
"K": 2,
"T": 1,
"O": 1
}
}
}
If weights are missing, the default value 1 is used for all categories.
4. File format: votes.txt
Data is stored in rows with pipe separation (|) to be easy to read and quick to parse:
Judge|Image Index|I|K|T|O|Competition ID|Status
- Status R: Ready - Counted in results.
- Status D: Draft (Draft/Not ready) - Only shown to the referee.
5. Version history
- 2026-02-21: Added technical JSON description for weighting in
image-docs.shtml. - 2026-02-21: Implemented session guard in
bild-judge.php. - 2026-02-21: Added visual progress bar for judges.
- 2026-02-12: Enabled Total Points as tie-breaker logic.