Skip to content

engrshishir/roxnor

Repository files navigation

πŸš€ Roxnor - PHP Form Submission System with Authentication

PHP MySQL Docker License

A professional web application built with pure PHP following MVC architecture, OOP principles, PSR-4 autoloading, and PSR-1 naming conventions. Features user authentication, validated form submission, and comprehensive reportingβ€”all containerized with Docker for easy deployment.

πŸ“– Documentation β€’ 🎯 Features β€’ 🐳 Docker Setup β€’ πŸ—οΈ Architecture

πŸ“Έ

User Signup

Signup Page Clean and intuitive registration interface with real-time validation

User Login

Login Page Secure authentication with session management

Data Submission Dashboard

Submission Dashboard Interactive form with dynamic item addition and validation

Reports & Analytics

Reports Page Comprehensive reporting with filtering options


πŸ› οΈ Technology Stack

Category Technology
Backend PHP 8.1
Database MySQL 8.0
Frontend JavaScript (Vanilla), HTML5, CSS3
Containerization Docker & Docker Compose
Dependency Management Composer
Database Management phpMyAdmin
Architecture MVC, Repository Pattern, Service Layer
OOP Principles All 4 Pillars Implemented
Autoloading PSR-4
Coding Standards PSR-1, PSR-12

πŸ—οΈ How This Project Works

This project follows a clean, layered architecture that separates concerns and promotes maintainability, testability, and scalability.

πŸ”„ Request Flow

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                          CLIENT REQUEST                         β”‚
β”‚                    (Browser β†’ HTTP Request)                     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                             β”‚
                             β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                      PUBLIC ENTRY POINT                         β”‚
β”‚                   (public/signup.php, etc.)                     β”‚
β”‚                  - Composer Autoload                            β”‚
β”‚                  - Session Management                           β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                             β”‚
                             β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                         CONTROLLER                              β”‚
β”‚               (AuthController, SubmissionController)            β”‚
β”‚                  - Handle HTTP Request                          β”‚
β”‚                  - Route to Appropriate Method                  β”‚
β”‚                  - Authentication Check                         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                             β”‚
                             β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                          VALIDATOR                              β”‚
β”‚            (UserSignupValidator, SubmissionValidator)           β”‚
β”‚                  - Validate Input Data                          β”‚
β”‚                  - Apply Business Rules                         β”‚
β”‚                  - Return Errors if Invalid                     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                             β”‚
                             β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                          SERVICE                                β”‚
β”‚               (AuthService, SubmissionService)                  β”‚
β”‚                  - Execute Business Logic                       β”‚
β”‚                  - Coordinate Operations                        β”‚
β”‚                  - Handle Transactions                          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                             β”‚
                             β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                         REPOSITORY                              β”‚
β”‚              (UserRepository, SubmissionRepository)             β”‚
β”‚                  - Database Operations (CRUD)                   β”‚
β”‚                  - Query Building                               β”‚
β”‚                  - Data Mapping                                 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                             β”‚
                             β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                       DATABASE MODEL                            β”‚
β”‚                      (Database Singleton)                       β”‚
β”‚                  - PDO Connection                               β”‚
β”‚                  - Query Execution                              β”‚
β”‚                  - Transaction Management                       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                             β”‚
                             β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                      MySQL DATABASE                             β”‚
β”‚                  - Data Persistence                             β”‚
β”‚                  - ACID Compliance                              β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                             β”‚
                             β–Ό (Response flows back up)
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                            VIEW                                 β”‚
β”‚                   (dashboard.php, reports.php)                  β”‚
β”‚                  - Render HTML                                  β”‚
β”‚                  - Display Data                                 β”‚
β”‚                  - User Interface                               β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                             β”‚
                             β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                      CLIENT RESPONSE                            β”‚
β”‚                   (Browser renders page)                        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

🎯 MVC Architecture

This project implements the Model-View-Controller pattern:

Model Layer (Data & Business Logic)

  • Database.php: Singleton pattern for database connections
  • Repositories: Handle all database operations (CRUD)
  • Services: Contain business logic and orchestrate operations

View Layer (Presentation)

  • app/Views/: Reusable view components
  • public/: Public-facing pages
  • JavaScript files: Client-side validation and interactivity

Controller Layer (Request Handling)

  • AuthController: Handles authentication (signup, login, logout)
  • SubmissionController: Manages form submissions and reports
  • AbstractController: Base controller with shared functionality

πŸ—„οΈ Repository Pattern

The Repository Pattern abstracts data access and provides a collection-like interface:

AbstractRepository (Base CRUD Operations)
    ↓
UserRepository (User-specific queries)
    - findByEmail()
    - emailExists()
    - verifyPassword()
    
SubmissionRepository (Submission-specific queries)
    - getFiltered()
    - findByReceiptId()
    - generateHashKey()

πŸ”§ Service Layer

The Service Layer contains business logic and coordinates between controllers and repositories:

AuthService
    - register(name, email, password)
    - login(email, password)
    - Coordinates: Validator β†’ Repository
    
SubmissionService
    - createSubmission(data)
    - getFilteredSubmissions(filters)
    - Coordinates: Validator β†’ Repository β†’ Business Rules

Benefits:

  • Separates business logic from controllers
  • Reusable across multiple entry points
  • Easier to test
  • Follows Single Responsibility Principle

🎨 OOP Implementation

This project is a comprehensive demonstration of Object-Oriented Programming principles applied to real-world web development.

The Four Pillars of OOP

1️⃣ Encapsulation - Data Hiding

Definition: Bundling data and methods together while restricting direct access.

Implementation:

class AbstractRepository {
    protected $connection;
    protected $table;
    
    protected function query($sql, $params) {
    }
}

Examples in Project:

  • AuthService: Private properties $userRepository, $errors, $response
  • AbstractController: Protected session management methods
  • All repositories: Protected database connection

2️⃣ Inheritance - Code Reuse

Definition: Child classes inherit properties and methods from parent classes.

Implementation:

// Parent provides base CRUD operations
AbstractRepository
    ↓
UserRepository extends AbstractRepository
    - Inherits: all(), findById(), create(), update(), delete()
    - Adds: findByEmail(), emailExists()

Class Hierarchies:

AbstractController
    β”œβ”€β”€ AuthController
    └── SubmissionController

AbstractRepository
    β”œβ”€β”€ UserRepository
    └── SubmissionRepository

AbstractValidator
    β”œβ”€β”€ UserSignupValidator
    β”œβ”€β”€ UserLoginValidator
    └── SubmissionValidator

3️⃣ Polymorphism - Multiple Forms

Definition: Same method name behaves differently in different classes.

Implementation:

// Parent method
class AbstractRepository {
    public function create(array $data): bool {
        // Generic create
    }
}

// Child overrides with specific behavior
class UserRepository extends AbstractRepository {
    public function create(array $data): bool {
        $data['password'] = password_hash($data['password'], PASSWORD_DEFAULT);
        return parent::create($data);  // Calls parent with hashed password
    }
}

Examples:

  • All validators implement validateRules() differently
  • Controllers implement request handlers polymorphically
  • Services implement execute() with different business logic

4️⃣ Abstraction - Hiding Complexity

Definition: Hiding implementation details while exposing essential features.

Implementation:

interface RepositoryInterface {
    public function all(): array;
    public function findById(int $id): ?array;
    public function create(array $data): bool;
    // Defines WHAT, not HOW
}

abstract class AbstractValidator implements ValidatorInterface {
    abstract protected function validateRules(array $data): void;
    // Forces children to implement specific validation
}

Interfaces in Project:

  • RepositoryInterface: Defines data access contract
  • ValidatorInterface: Defines validation contract
  • AuthenticationInterface: Defines auth operations contract
  • ServiceInterface: Defines service operations contract

πŸ“Š Class Hierarchy

Repository Hierarchy

RepositoryInterface (Contract)
    ↓
AbstractRepository (Implementation + Helpers)
    β”œβ”€β”€ UserRepository (User-specific operations)
    └── SubmissionRepository (Submission-specific operations)

Validator Hierarchy

ValidatorInterface (Contract)
    ↓
AbstractValidator (Base validation + Helpers)
    β”œβ”€β”€ UserSignupValidator
    β”œβ”€β”€ UserLoginValidator
    └── SubmissionValidator

Controller Hierarchy

AbstractController (Base functionality)
    β”œβ”€β”€ AuthController (Authentication operations)
    └── SubmissionController (Submission operations)

🎯 Design Patterns Used

1. Singleton Pattern

class Database {
    private static $instance = null;
    
    public static function getInstance() {
        if (self::$instance === null) {
            self::$instance = new self();
        }
        return self::$instance;
    }
}

Purpose: Ensures only one database connection exists.

2. Repository Pattern

Purpose: Abstracts data layer and provides collection-like interface.

3. Service Layer Pattern

Purpose: Separates business logic from controllers.

4. Dependency Injection

class AuthController extends AbstractController {
    private $authService;
    private $validator;
    
    public function __construct(AuthService $authService, UserSignupValidator $validator) {
        $this->authService = $authService;
        $this->validator = $validator;
    }
}

Purpose: Loose coupling and easier testing.

5. MVC (Model-View-Controller)

Purpose: Separation of concerns.


🐳 Docker Setup Guide

This project uses Docker to containerize the entire application stack, making it portable, consistent, and easy to deploy across different environments.

πŸ›οΈ Container Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                      Docker Host                             β”‚
β”‚                                                              β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚                  roxnor_network (Bridge)               β”‚  β”‚
β”‚  β”‚                                                        β”‚  β”‚ 
β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚  β”‚
β”‚  β”‚  β”‚   PHP App    β”‚  β”‚    MySQL     β”‚  β”‚  phpMyAdmin  β”‚  β”‚  β”‚
β”‚  β”‚  β”‚  Container   β”‚  β”‚  Container   β”‚  β”‚  Container   β”‚  β”‚  β”‚
β”‚  β”‚  β”‚              β”‚  β”‚              β”‚  β”‚              β”‚  β”‚  β”‚
β”‚  β”‚  β”‚ Port: 8080   β”‚  β”‚ Port: 3307   β”‚  β”‚ Port: 8081   β”‚  β”‚  β”‚
β”‚  β”‚  β”‚              β”‚  β”‚              β”‚  β”‚              β”‚  β”‚  β”‚
β”‚  β”‚  β”‚ PHP 8.1      β”‚  β”‚ MySQL 8.0    β”‚  β”‚ phpMyAdmin   β”‚  β”‚  β”‚
β”‚  β”‚  β”‚ Apache       β”‚  β”‚              β”‚  β”‚ Latest       β”‚  β”‚  β”‚
β”‚  β”‚  β”‚ Composer     β”‚  β”‚              β”‚  β”‚              β”‚  β”‚  β”‚
β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚  β”‚
β”‚  β”‚         β”‚                 β”‚                 β”‚          β”‚  β”‚
β”‚  β”‚         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜          β”‚  β”‚
β”‚  β”‚                   Inter-container                      β”‚  β”‚
β”‚  β”‚                   Communication                        β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚                                                              β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚                Docker Volumes (Persistent)             β”‚  β”‚
β”‚  β”‚                                                        β”‚  β”‚ 
β”‚  β”‚  β€’ db_data β†’ MySQL data persistence                    β”‚  β”‚
β”‚  β”‚  β€’ ./:/var/www/html β†’ App code mounting                β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ“‚ Project Structure

roxnor/
β”œβ”€β”€ app/                              # Application logic
β”‚   β”œβ”€β”€ Abstracts/                    # Abstract base classes
β”‚   β”‚   β”œβ”€β”€ AbstractController.php    # Base controller functionality
β”‚   β”‚   β”œβ”€β”€ AbstractRepository.php    # Base CRUD operations
β”‚   β”‚   └── AbstractValidator.php     # Base validation helpers
β”‚   β”œβ”€β”€ Contracts/                    # Interfaces (Abstraction)
β”‚   β”‚   β”œβ”€β”€ AuthenticationInterface.php
β”‚   β”‚   β”œβ”€β”€ DatabaseInterface.php
β”‚   β”‚   β”œβ”€β”€ RepositoryInterface.php
β”‚   β”‚   β”œβ”€β”€ ServiceInterface.php
β”‚   β”‚   └── ValidatorInterface.php
β”‚   β”œβ”€β”€ Controllers/                  # Request handlers
β”‚   β”‚   β”œβ”€β”€ AuthController.php        # Authentication logic
β”‚   β”‚   └── SubmissionController.php  # Submission logic
β”‚   β”œβ”€β”€ Models/                       # Database models
β”‚   β”‚   └── Database.php              # Singleton DB connection
β”‚   β”œβ”€β”€ Repositories/                 # Data access layer
β”‚   β”‚   β”œβ”€β”€ UserRepository.php        # User CRUD operations
β”‚   β”‚   └── SubmissionRepository.php  # Submission CRUD operations
β”‚   β”œβ”€β”€ Services/                     # Business logic layer
β”‚   β”‚   β”œβ”€β”€ AuthService.php           # Auth business logic
β”‚   β”‚   └── SubmissionService.php     # Submission business logic
β”‚   β”œβ”€β”€ Validators/                   # Input validation
β”‚   β”‚   β”œβ”€β”€ UserSignupValidator.php
β”‚   β”‚   β”œβ”€β”€ UserLoginValidator.php
β”‚   β”‚   └── SubmissionValidator.php
β”‚   └── Views/
β”‚       β”œβ”€β”€ dashboard.php
β”‚       β”œβ”€β”€ login.php
β”‚       β”œβ”€β”€ signup.php
β”‚       β”œβ”€β”€ reports.php
β”‚       └── partials/
β”‚           β”œβ”€β”€ head.php
β”‚           β”œβ”€β”€ navbar.php
β”‚           └── input.php
β”œβ”€β”€ config/                           # Configuration files
β”‚   β”œβ”€β”€ app.php                       # App configuration
β”‚   └── database.php                  # Database configuration
β”œβ”€β”€ public/                           # Public web root
β”‚   β”œβ”€β”€ css/                          # Stylesheets
β”‚   β”œβ”€β”€ js/                           # JavaScript files
β”‚   β”œβ”€β”€ Images/                       # Images
β”‚   β”œβ”€β”€ api/                          # API endpoints
β”‚   β”œβ”€β”€ index.php                     # Entry point
β”‚   β”œβ”€β”€ signup.php                    # Signup page
β”‚   β”œβ”€β”€ login.php                     # Login page
β”‚   β”œβ”€β”€ dashboard.php                 # Dashboard page
β”‚   β”œβ”€β”€ submit.php                    # Form submission handler
β”‚   β”œβ”€β”€ logout.php                    # Logout handler
β”‚   └── reports.php                   # Reports page
β”œβ”€β”€ vendor/                           # Composer dependencies
β”œβ”€β”€ Instructions/                     # Project documentation
β”œβ”€β”€ composer.json                     # Composer configuration
β”œβ”€β”€ database.sql                      # Database schema
β”œβ”€β”€ Dockerfile                        # PHP app container config
β”œβ”€β”€ docker-compose.yml                # Multi-container orchestration
└── README.md                         # This file

πŸš€ Installation & Setup

Option 1: Using Docker (Recommended) 🐳

1. Clone the repository

git clone https://github.com/engrshishir/roxnor.git
cd roxnor

2. Build and start containers

docker-compose up -d --build

This command will:

  • βœ… Build the PHP 8.1 + Apache container
  • βœ… Pull MySQL 8.0 image
  • βœ… Pull phpMyAdmin image
  • βœ… Create isolated network
  • βœ… Initialize database with schema
  • βœ… Install Composer dependencies

3. Access the application

Docker Management Commands

# View logs
docker-compose logs -f

# Stop containers
docker-compose down

# Restart containers
docker-compose restart

# Rebuild after code changes
docker-compose up -d --build

# Remove containers and volumes (fresh start)
docker-compose down -v

πŸ—οΈ Architecture Diagrams

System Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                      PRESENTATION LAYER                 β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚  HTML5   β”‚  β”‚   CSS3   β”‚  β”‚JavaScriptβ”‚  β”‚  Views  β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                         β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                   CONTROLLER LAYER                      β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”‚
β”‚  β”‚  AuthController    β”‚  β”‚  SubmissionController   β”‚    β”‚
β”‚  β”‚  - signup()        β”‚  β”‚  - create()             β”‚    β”‚
β”‚  β”‚  - login()         β”‚  β”‚  - getFiltered()        β”‚    β”‚
β”‚  β”‚  - logout()        β”‚  β”‚  - update()             β”‚    β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                         β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                   VALIDATION LAYER                      β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚  UserSignup   β”‚  β”‚  UserLogin   β”‚  β”‚ Submission   β”‚  β”‚
β”‚  β”‚  Validator    β”‚  β”‚  Validator   β”‚  β”‚  Validator   β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                         β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    SERVICE LAYER                        β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”‚
β”‚  β”‚   AuthService      β”‚  β”‚  SubmissionService      β”‚    β”‚
β”‚  β”‚  - Business Logic  β”‚  β”‚  - Business Logic       β”‚    β”‚
β”‚  β”‚  - Orchestration   β”‚  β”‚  - Orchestration        β”‚    β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                         β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                   REPOSITORY LAYER                      β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”‚
β”‚  β”‚  UserRepository    β”‚  β”‚  SubmissionRepository   β”‚    β”‚
β”‚  β”‚  - CRUD Operations β”‚  β”‚  - CRUD Operations      β”‚    β”‚
β”‚  β”‚  - Data Mapping    β”‚  β”‚  - Query Building       β”‚    β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                         β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                      DATA LAYER                         β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚  Database (Singleton PDO)                        β”‚   β”‚
β”‚  β”‚  - Connection Management                         β”‚   β”‚
β”‚  β”‚  - Query Execution                               β”‚   β”‚
β”‚  β”‚  - Transaction Handling                          β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                         β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    MySQL DATABASE                       β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”           β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”‚
β”‚  β”‚  users table   β”‚           β”‚ submissions table  β”‚    β”‚
β”‚  β”‚  - id          β”‚           β”‚ - id               β”‚    β”‚
β”‚  β”‚  - name        β”‚           β”‚ - receipt_id       β”‚    β”‚
β”‚  β”‚  - email       │───────────│ - entry_by (FK)    β”‚    β”‚
β”‚  β”‚  - password    β”‚           β”‚ - total_amount     β”‚    β”‚
β”‚  β”‚  - created_at  β”‚           β”‚ - items (JSON)     β”‚    β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜           β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

🀝 Contributing

Contributions are welcome! Please follow these guidelines:

  1. Fork the repository
  2. Create a feature branch
    git checkout -b feature/YourFeature
  3. Commit your changes
    git commit -m "Add: Your feature description"
  4. Push to the branch
    git push origin feature/YourFeature
  5. Open a Pull Request

Code Standards

  • Follow PSR-1 and PSR-12 coding standards
  • Write meaningful commit messages
  • Add comments for complex logic
  • Update documentation if needed

πŸ“„ License

This project is licensed under the MIT License.

⭐ If you find this project helpful, please give it a star!

🐳 Docker Hub

Image: engrshishir/roxnor-app

Pull and Run

# Pull the latest image
docker pull engrshishir/roxnor-app:latest

# Or pull specific version
docker pull engrshishir/roxnor-app:1.0.0

# Clone repository for docker-compose.yml
git clone https://github.com/engrshishir/roxnor.git
cd roxnor

# Start all services (app, database, phpMyAdmin)
docker-compose up -d

# Access the application
# - App: http://localhost:8080
# - phpMyAdmin: http://localhost:8081

Author

Shishir - Roxnor Internship Assessment

License

This project is created for internship assessment purposes.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published