Skip to content

About

Config files for my GitHub profile.

Topics

Resources

Stars

0 stars

Watchers

1 watching

Forks

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SKPROPERTY

Live. Build. Belong.

A complete, responsive real-estate marketplace for Sri Lanka, built with plain PHP 8, MySQL/MariaDB and Bootstrap 5. Buyers can search land, houses, apartments, villas and commercial property; sellers can publish and manage their own advertisements; and homeowners can discover architects and building contractors in a reviewed professional directory.

The project preserves the identity of the original SKPROPERTY (formerly 4EverLands) university project while replacing the legacy code with a secure, maintainable application.

SKPROPERTY homepage


Table of contents


Screenshots

Public marketplace Property details
Marketplace Property details
Professionals directory Admin dashboard
Professionals Admin dashboard

Screenshots are stored in docs/screenshots/. Replace them with fresh captures after customising the site.


Features

Public website

  • Editorial-style homepage with a search panel, featured listings, category shortcuts, professional spotlight and trust signals.
  • Marketplace with keyword, category, location, price range, feature and sort filters. Pagination preserves the active filters.
  • Property details page with an image gallery, specifications, description, seller card, WhatsApp and call actions, Google Maps embed and similar properties.
  • Architects and contractors directory with type, search and rating sorting.
  • Professional profiles with portfolio lightbox, experience, contact details and member reviews.
  • About, contact, FAQ, privacy policy and terms pages.
  • Fully responsive layouts for desktop, tablet and mobile, including a sticky mobile contact bar on listing pages.

Accounts and listings

  • Registration, login and logout with password_hash() / password_verify().
  • Session hardening, login throttling and CSRF protection on every state-changing form.
  • Member dashboard with listing statistics and status tracking.
  • Logged-in members only can post advertisements.
  • Full listing CRUD: create, edit and delete your own advertisements.
  • Multiple image uploads (up to 8) with MIME, size and image-content validation; primary image selection and safe deletion.
  • Automatic unique reference numbers and URL slugs.
  • New and edited member listings enter a pending approval queue before publication.

Professional directory

  • Profiles for architects and building contractors with specialisation, experience, bio, contact details and portfolio.
  • One review per member per professional, enforced by a database unique key.
  • Stars, average rating and review counts calculated from approved reviews.
  • Authors can edit or remove their own reviews; administrators can moderate them.

Admin dashboard

  • At-a-glance statistics for listings, pending approvals, members, professionals, reviews, unread messages and total views.
  • Property management with search, filters, approval/rejection, featured flags, editing and deletion.
  • Category management with display order, icons, descriptions and safe deletion rules.
  • Professional management with portfolio uploads and featured flags.
  • Review moderation queue (approve, unpublish, delete).
  • User management with search, role changes, account creation and protected deletion rules.
  • Contact inbox with read/unread state, reply links and bulk mark-as-read.
  • Role-based access control: the admin console is limited to role = 'admin' accounts, and the last administrator cannot be deleted or demoted.

Security and engineering

  • PDO prepared statements everywhere; no string-concatenated SQL user input.
  • Server-side validation for every form, with output escaped through a single e() helper.
  • CSRF tokens on authentication, listing, profile, review and admin actions.
  • Secure uploads: random filenames, allow-listed MIME types, getimagesize() verification, 5 MB limit and PHP execution disabled inside /uploads.
  • Session cookie hardening (HttpOnly, SameSite=Lax, Secure over HTTPS), strict mode and ID regeneration on login.
  • Security headers (X-Content-Type-Options, X-Frame-Options, Referrer-Policy, Permissions-Policy).
  • Friendly error handling with detailed errors only in local mode.
  • Dynamic XML sitemap, robots.txt, canonical URLs, Open Graph metadata and descriptive alt text.

Technology stack

Layer Technology
Server PHP 8.0+
Database MySQL 8 or MariaDB 10.4+
Data access PDO with prepared statements
Frontend HTML5, CSS3, JavaScript (ES6)
UI framework Bootstrap 5.3
Icons Font Awesome 6
Fonts Plus Jakarta Sans (Google Fonts)
Local environment XAMPP / Apache / MariaDB

No Node.js, React, Next.js, build step or paid dependency is required.


Project structure

Property-Sales-System/
├── admin/                     Admin console (dashboard, CRUD, moderation)
│   ├── actions.php            Central CSRF-protected POST handler
│   ├── categories.php
│   ├── index.php
│   ├── login.php
│   ├── messages.php
│   ├── professional-form.php
│   ├── professionals.php
│   ├── properties.php
│   ├── property-form.php
│   ├── reviews.php
│   ├── users.php
│   └── includes/              Admin header/footer layout
├── assets/
│   ├── css/                   Public and admin design systems
│   ├── img/                   Brand, property and professional imagery
│   └── js/                    Navigation, gallery, lightbox and form behaviour
├── docs/screenshots/          README screenshots
├── includes/
│   ├── bootstrap.php          Config, session, headers and base URL
│   ├── db.php                 PDO singleton and query helpers
│   ├── functions.php          Escaping, CSRF, uploads, pagination
│   ├── auth.php               Authentication and RBAC
│   ├── catalog.php            Property, professional and review queries
│   ├── property-validation.php
│   ├── property-form.php      Shared member/admin listing form
│   ├── header.php / footer.php
│   ├── property-card.php
│   ├── professional-card.php
│   ├── config.example.php
│   └── config.php             Local only – ignored by Git
├── legacy/                    Original site preserved for reference
├── sql/skproperty.sql         Complete schema + demo data
├── uploads/                   User uploads (PHP execution disabled)
├── .htaccess                  Security headers, blocking and sitemap rewrite
├── robots.txt
├── sitemap.php
├── index.php
├── properties.php
├── property.php
├── professionals.php
├── professional.php
├── login.php / register.php / logout.php
├── dashboard.php / profile.php
├── post-property.php / edit-property.php / delete-property.php
├── review.php / contact.php / about.php / faq.php
├── privacy.php / terms.php
└── README.md

Requirements

  • PHP 8.0 or newer with pdo_mysql, fileinfo and mbstring extensions.
  • MySQL 8.0+ or MariaDB 10.4+.
  • Apache with mod_rewrite for the clean /sitemap.xml route (optional).
  • A modern browser.

Local installation with XAMPP

1. Install XAMPP

Download XAMPP from https://www.apachefriends.org/ and install it. Start Apache and MySQL from the XAMPP Control Panel.

2. Place the project in the web root

Copy this folder to:

C:\xampp\htdocs\Property-Sales-System

3. Create the configuration file

Copy includes/config.example.php to includes/config.php:

Copy-Item includes\config.example.php includes\config.php

The default XAMPP values normally work:

define('DB_HOST', '127.0.0.1');
define('DB_PORT', '3306');
define('DB_NAME', 'skproperty');
define('DB_USER', 'root');
define('DB_PASS', '');
define('APP_ENV', 'local');
define('APP_URL', ''); // auto-detect

If your MySQL root account has a password, set DB_PASS accordingly. Never commit includes/config.php.

4. Import the database

Option A – phpMyAdmin

  1. Open http://localhost/phpmyadmin.
  2. Choose Import.
  3. Select sql/skproperty.sql and click Go.
  4. The script creates the skproperty database, all tables and demo content.

Option B – command line

C:\xampp\mysql\bin\mysql.exe -u root < sql\skproperty.sql

5. Create the upload folders

The application creates them automatically on the first upload, but you can prepare them now:

New-Item -ItemType Directory -Force uploads\properties, uploads\professionals\portfolio | Out-Null

On Linux/macOS, make them writable by the web-server user:

chmod -R 775 uploads

6. Open the website

http://localhost/Property-Sales-System/

Admin console:

http://localhost/Property-Sales-System/admin/login.php

Troubleshooting

Problem Fix
“Configuration missing” Copy includes/config.example.php to includes/config.php.
“Database connection failed” Start MySQL in XAMPP and confirm the credentials in includes/config.php.
“Unknown database skproperty” Import sql/skproperty.sql again.
Images do not upload Check that uploads/ exists and is writable by Apache.
/sitemap.xml returns 404 Enable mod_rewrite in Apache, or open sitemap.php directly.
Blank page Set APP_ENV to local and check the Apache/PHP error log.

Running without Apache

PHP’s built-in server is enough for development and testing:

cd C:\Users\asust\Desktop\Property-Sales-System
C:\xampp\php\php.exe -S 127.0.0.1:8080 -t .

Then open http://127.0.0.1:8080/. The built-in server does not read .htaccess, so use sitemap.php directly instead of /sitemap.xml, and uploads are still protected by the validation code.


Demo accounts

Role Email Password Purpose
Administrator admin@skproperty.lk Admin@123 Full admin console access
Member / seller demo@skproperty.lk Demo@123 Demo listings and reviews
Member / seller seller@skproperty.lk Seller@123 Additional demo listings
Member / buyer buyer@skproperty.lk Buyer@123 Reviewing professionals

These accounts exist only in the demo SQL file. Change or delete them before deploying to a public server.

The seed data includes:

  • 9 properties across 5 categories (approved, pending and rejected examples).
  • 4 professional profiles with portfolios.
  • 6 reviews (including one pending moderation example).
  • 4 contact messages (including unread examples).

Configuration

All configuration lives in includes/config.php:

Constant Description
DB_HOST, DB_PORT, DB_NAME, DB_USER, DB_PASS Database connection
APP_NAME Site name used in titles and meta tags
APP_ENV local shows detailed errors; production hides them
APP_URL Optional absolute URL. Leave empty for auto-detection in XAMPP sub-folders
MAX_IMAGE_SIZE Maximum bytes per uploaded image (default 5 MB)
MAX_PROPERTY_IMAGES Maximum images per property (default 8)

For production, set APP_ENV to production, use a dedicated database user with minimal privileges, and ideally set APP_URL to the canonical HTTPS domain.


Database overview

Table Purpose
users Members and administrators, bcrypt password hashes, role, avatar, bio and login timestamps
categories Land, Houses, Apartments, Villas, Commercial with slug, icon and sort order
properties One normalised listing table with category/user foreign keys, price, area, rooms, status, approval state, featured flag and view counter
property_images Multiple gallery images per property with primary and sort flags
professionals Architects and contractors with specialisation, experience and contact details
professional_images Portfolio images per professional
reviews 1–5 star reviews with unique (professional_id, user_id) constraint and moderation status
contact_messages Contact form inbox with read/unread state

Relationships use InnoDB foreign keys with cascading deletes for dependent content. Category deletion is restricted while properties still reference it.


Security

  • SQL injection: every query uses PDO prepared statements with bound parameters.
  • Passwords: password_hash() with bcrypt and automatic rehashing on login.
  • CSRF: a per-session token is required by all POST handlers.
  • Validation: server-side checks for names, emails, phone numbers, prices, dates, areas, ratings and uploads.
  • XSS: all dynamic output passes through the e() escaping helper; review text and descriptions are stored as plain text.
  • Uploads: random file names, allow-listed MIME types, image verification, size limits, path traversal protection and PHP execution disabled in /uploads.
  • Sessions: strict mode, HttpOnly/SameSite cookies, regeneration after login and full destruction on logout.
  • Access control: require_login(), require_owner_or_admin() and require_admin() gate every protected action.
  • Admin safety: the last administrator cannot be deleted or demoted, and admins cannot delete or demote themselves.
  • Error handling: production hides exception details from visitors.

SEO and accessibility

  • Unique page titles and meta descriptions on every public page.
  • Canonical URLs, Open Graph tags and semantic HTML5 landmarks.
  • Descriptive alt text on property and professional imagery.
  • Accessible labels, focus styles, skip link and keyboard-friendly navigation.
  • Dynamic sitemap.xml (served by sitemap.php) containing static pages, approved properties and professional profiles.
  • robots.txt keeps private and admin areas out of search results.
  • Responsive images and lazy-loaded galleries.

Deployment checklist

  1. Set APP_ENV to production.
  2. Create a dedicated MySQL user and grant only the required privileges.
  3. Set strong credentials in includes/config.php (never commit the file).
  4. Import sql/skproperty.sql, then change the demo passwords or delete demo accounts.
  5. Ensure uploads/ is writable but cannot execute PHP.
  6. Serve the site over HTTPS and enable mod_rewrite.
  7. Update the Sitemap: domain in robots.txt.
  8. Review backups and error logging.

Credits

The original university project is preserved in legacy/ for reference. It is not used by the new application.


License

Released for educational and portfolio use. Third-party images, fonts and icon sets remain subject to their respective licences.

About

Config files for my GitHub profile.

Topics

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages