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.
- Screenshots
- Features
- Technology stack
- Project structure
- Requirements
- Local installation with XAMPP
- Running without Apache
- Demo accounts
- Configuration
- Database overview
- Security
- SEO and accessibility
- Deployment checklist
- Credits
- License
| Public marketplace | Property details |
|---|---|
![]() |
![]() |
| Professionals directory | Admin dashboard |
|---|---|
![]() |
![]() |
Screenshots are stored in
docs/screenshots/. Replace them with fresh captures after customising the site.
- 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.
- 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
pendingapproval queue before publication.
- 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.
- 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.
- 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,Secureover 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.
| 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.
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
- PHP 8.0 or newer with
pdo_mysql,fileinfoandmbstringextensions. - MySQL 8.0+ or MariaDB 10.4+.
- Apache with
mod_rewritefor the clean/sitemap.xmlroute (optional). - A modern browser.
Download XAMPP from https://www.apachefriends.org/ and install it. Start Apache and MySQL from the XAMPP Control Panel.
Copy this folder to:
C:\xampp\htdocs\Property-Sales-System
Copy includes/config.example.php to includes/config.php:
Copy-Item includes\config.example.php includes\config.phpThe 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-detectIf your MySQL root account has a password, set DB_PASS accordingly. Never commit includes/config.php.
Option A – phpMyAdmin
- Open http://localhost/phpmyadmin.
- Choose Import.
- Select
sql/skproperty.sqland click Go. - The script creates the
skpropertydatabase, all tables and demo content.
Option B – command line
C:\xampp\mysql\bin\mysql.exe -u root < sql\skproperty.sqlThe 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-NullOn Linux/macOS, make them writable by the web-server user:
chmod -R 775 uploadshttp://localhost/Property-Sales-System/
Admin console:
http://localhost/Property-Sales-System/admin/login.php
| 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. |
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.
| Role | 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).
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.
| 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.
- 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()andrequire_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.
- 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 bysitemap.php) containing static pages, approved properties and professional profiles. robots.txtkeeps private and admin areas out of search results.- Responsive images and lazy-loaded galleries.
- Set
APP_ENVtoproduction. - Create a dedicated MySQL user and grant only the required privileges.
- Set strong credentials in
includes/config.php(never commit the file). - Import
sql/skproperty.sql, then change the demo passwords or delete demo accounts. - Ensure
uploads/is writable but cannot execute PHP. - Serve the site over HTTPS and enable
mod_rewrite. - Update the
Sitemap:domain inrobots.txt. - Review backups and error logging.
- Property and interior photography: Unsplash (downloaded locally for the demo).
- Professional portraits: randomuser.me.
- Icons: Font Awesome.
- UI framework: Bootstrap.
- Typeface: Plus Jakarta Sans.
The original university project is preserved in legacy/ for reference. It is not used by the new application.
Released for educational and portfolio use. Third-party images, fonts and icon sets remain subject to their respective licences.




