Skip to content

nityam2007/bookmark-php

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

14 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Bookmark Manager

A production-ready, fast, and modular bookmark management system built with PHP 8.2+ and MySQL/MariaDB. Designed for both Docker deployment and cPanel shared hosting with a focus on speed, security, and maintainability.

Features

  • ⚑ Fast Search - Full-text search with AJAX and client-side caching
  • πŸ“ Nested Categories - Support for up to 10 levels of category hierarchy
  • 🏷️ Flexible Tagging - Tag bookmarks for quick filtering
  • πŸ“₯ Import/Export - Support for JSON, HTML (browser format), and CSV
  • πŸ“₯ Smart Duplicate Detection - Skip duplicates only when URL AND category match exactly
  • πŸŒ™ Dark Mode - Automatic theme detection with manual toggle
  • πŸ”’ Secure by Default - CSRF protection, XSS prevention, prepared statements
  • πŸ‡ͺπŸ‡Ί GDPR Compliant - Cookie consent and data privacy features
  • πŸ“± Responsive Design - Mobile-first approach
  • ⌨️ Keyboard Shortcuts - Power user friendly
  • 🐳 Docker Ready - Easy deployment with Docker Compose
  • πŸ–ΌοΈ Image Caching - Automatic favicon and image caching (weekly refresh for bandwidth efficiency)
  • πŸ–ΌοΈ Image URL Support - Save image URLs directly with automatic offloading/caching
  • πŸ”„ Meta Fetching - Automatic title and description extraction from URLs
  • 🧩 Browser Extension - Chrome/Edge extension for quick bookmark saving
  • πŸ› οΈ Web Installer - Easy setup wizard for shared hosting

Requirements

For Docker Deployment

  • Docker Engine 20.10+
  • Docker Compose 2.0+

For Manual/Shared Hosting Installation

  • PHP 8.1 or higher
  • MySQL 8.0+ or MariaDB 10.5+
  • Apache with mod_rewrite (or nginx)
  • Required PHP extensions: pdo, pdo_mysql, json, mbstring, curl, openssl

Installation

Option 1: Docker (Recommended)

The easiest way to get started is using Docker:

# Clone the repository
git clone <repository-url>
cd bookmark-manager

# Start the containers
docker compose up -d

The application will be available at http://localhost:8080.

Default Docker Configuration:

  • Web Server: http://localhost:8080
  • MySQL: localhost:3306
  • Database: bookmarks_db
  • User: bookmark_user
  • Password: bookmark_pass

Option 2: Web Installer (Shared Hosting)

For cPanel, Plesk, or any shared hosting with PHP 8.1+ and MySQL:

Method A: Upload to public_html directly (easiest)

  1. Upload Files - Upload ALL files to public_html via FTP/File Manager
  2. Run Installer - Visit https://yourdomain.com/install.php
  3. Follow Wizard - Configure database, create admin account
  4. Delete Installer - Remove install.php after installation

The root .htaccess and index.php will route requests properly.

Method B: Subdirectory with custom document root (if available)

  1. Upload files to /home/user/bookmark-manager/
  2. In cPanel, set domain document root to /home/user/bookmark-manager/public
  3. Visit https://yourdomain.com/install.php

Option 3: Manual Installation

1. Upload Files

Upload all files to your web hosting. The public folder should be your document root.

/home/username/
β”œβ”€β”€ bookmark-manager/       # Application root
β”‚   β”œβ”€β”€ app/               # Application code
β”‚   β”œβ”€β”€ cache/             # Cache storage
β”‚   β”œβ”€β”€ cron/              # Cron scripts
β”‚   β”œβ”€β”€ database/          # Database schema
β”‚   └── public/            # Document root (point domain here)

2. Create Database

Create a new MySQL database via cPanel and import the schema:

mysql -u username -p database_name < database/schema.sql

Or use phpMyAdmin to import database/schema.sql.

3. Configure Application

Copy the example config and edit with your settings:

cp app/config/config.example.json app/config/config.json

Edit config.json:

{
    "database": {
        "host": "localhost",
        "name": "your_database",
        "user": "your_username",
        "password": "your_password"
    },
    "app": {
        "url": "https://yourdomain.com"
    }
}

4. Set Permissions

chmod 755 -R app/
chmod 777 cache/
chmod 777 logs/
chmod 644 app/config/config.json

5. Set Up Cron Jobs (Optional)

In cPanel > Cron Jobs, add:

# Refresh bookmark metadata weekly (Sunday 4 AM)
0 4 * * 0 /usr/local/bin/php /home/username/bookmark-manager/cron/refresh-meta.php

# Cache bookmark images weekly (Sunday 3 AM) - bandwidth efficient
0 3 * * 0 /usr/local/bin/php /home/username/bookmark-manager/cron/cache-images.php

# Cleanup expired cache weekly (Sunday 2 AM)
0 2 * * 0 /usr/local/bin/php /home/username/bookmark-manager/cron/cleanup.php

6. Create Admin User

Visit https://yourdomain.com/register to create your first account.

Configuration Options

config.json

{
    "database": {
        "host": "localhost",
        "name": "bookmarks",
        "user": "root",
        "password": "",
        "charset": "utf8mb4"
    },
    "app": {
        "name": "Bookmark Manager",
        "url": "http://localhost",
        "debug": false,
        "timezone": "UTC",
        "per_page": 20
    },
    "security": {
        "session_lifetime": 7200,
        "password_algo": "argon2id"
    },
    "cache": {
        "enabled": true,
        "ttl": 3600,
        "driver": "file"
    },
    "gdpr": {
        "enabled": true,
        "cookie_consent": true,
        "data_retention_days": 365
    }
}

Folder Structure

bookmark-manager/
β”œβ”€β”€ app/
β”‚   β”œβ”€β”€ api/              # API endpoints (bookmarks, export, import, meta, search)
β”‚   β”œβ”€β”€ config/           # Configuration files
β”‚   β”œβ”€β”€ controllers/      # Request handlers
β”‚   β”œβ”€β”€ core/             # Core framework classes (Autoloader, Database, Router, View)
β”‚   β”œβ”€β”€ helpers/          # Utility functions (Auth, CSRF, Sanitizer)
β”‚   β”œβ”€β”€ models/           # Database models (Bookmark, Category, Tag, User)
β”‚   β”œβ”€β”€ services/         # Business logic services
β”‚   β”‚   β”œβ”€β”€ CacheService.php
β”‚   β”‚   β”œβ”€β”€ EnhancedMetaFetcher.php
β”‚   β”‚   β”œβ”€β”€ ImageCacheService.php
β”‚   β”‚   β”œβ”€β”€ ImportExportService.php
β”‚   β”‚   β”œβ”€β”€ MetaFetcher.php
β”‚   β”‚   └── SearchService.php
β”‚   └── views/
β”‚       β”œβ”€β”€ components/   # Reusable UI components
β”‚       β”œβ”€β”€ layout.php    # Main layout template
β”‚       └── pages/        # Page templates
β”œβ”€β”€ cache/                # File-based cache storage
β”‚   └── images/           # Cached favicon and images
β”œβ”€β”€ cron/                 # Scheduled task scripts
β”‚   β”œβ”€β”€ cache-images.php
β”‚   β”œβ”€β”€ cleanup.php
β”‚   β”œβ”€β”€ fetch-meta.php
β”‚   └── refresh-meta.php
β”œβ”€β”€ database/             # SQL schema and migrations
β”‚   β”œβ”€β”€ schema.sql
β”‚   └── migrations/
β”œβ”€β”€ logs/                 # Application logs
β”œβ”€β”€ public/               # Web-accessible files
β”‚   β”œβ”€β”€ css/              # Stylesheets
β”‚   β”œβ”€β”€ js/               # JavaScript files
β”‚   β”œβ”€β”€ img/              # Images
β”‚   β”œβ”€β”€ errors/           # Error pages (404, 500)
β”‚   └── index.php         # Application entry point
β”œβ”€β”€ docker-compose.yml    # Docker Compose configuration
β”œβ”€β”€ Dockerfile            # Docker image definition
└── README.md             # This file

API Endpoints

Internal API (Session Auth)

These endpoints require session authentication (login via browser):

GET    /api/search?q=query&limit=10    # Search bookmarks
GET    /api/meta?url=https://example.com    # Fetch URL metadata
GET    /api/bookmarks                  # List bookmarks
POST   /api/bookmarks                  # Create bookmark
GET    /api/bookmarks/:id              # Get bookmark
PUT    /api/bookmarks/:id              # Update bookmark
DELETE /api/bookmarks/:id              # Delete bookmark

External API (API Key Auth)

For Chrome extensions, mobile apps, or other external integrations.

Authentication: Include your API key in the request header:

Authorization: Bearer bm_xxxxxxxxxxxxxxxxxxxx

Or use the X-API-Key header:

X-API-Key: bm_xxxxxxxxxxxxxxxxxxxx

Generate API Keys: Go to Settings β†’ API Keys in your dashboard.

Add Bookmark

POST /api/external.php

curl -X POST https://yourdomain.com/api/external.php \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com",
    "title": "Example Site",
    "description": "Optional description",
    "category": "Work",
    "tags": ["reference", "tools"],
    "is_favorite": true
  }'

Request Body:

Field Type Required Description
url string Yes The URL to bookmark
title string No Title (auto-fetched if empty)
description string No Description (auto-fetched if empty)
category string No Category name (created if doesn't exist)
category_id int No Category ID (takes precedence over name)
tags array No Array of tag names
is_favorite bool No Mark as favorite
fetch_meta bool No Auto-fetch title/description (default: true)

Response:

{
  "success": true,
  "message": "Bookmark created successfully",
  "data": {
    "id": 123,
    "url": "https://example.com",
    "title": "Example Site",
    ...
  }
}

List Bookmarks

GET /api/external.php?page=1&per_page=20

Get Single Bookmark

GET /api/external.php?id=123

Delete Bookmark

DELETE /api/external.php?id=123

Browser Extension

A Chrome/Edge/Brave extension is included for quickly saving bookmarks from any webpage.

Installation

  1. Open chrome://extensions/ (or edge://extensions/ for Edge)
  2. Enable Developer mode
  3. Click Load unpacked
  4. Select the browser-extension folder
  5. The extension icon will appear in your toolbar

Setup

  1. Click the extension icon β†’ Settings
  2. Enter your Server URL (e.g., http://127.0.0.1:8080)
  3. Enter your API Key (from Settings β†’ API Keys in your dashboard)
  4. Click Test Connection then Save

Usage

  1. Navigate to any webpage
  2. Click the extension icon
  3. Select a category (default: Uncategorized)
  4. Add tags (optional)
  5. Click Save Bookmark

See browser-extension/README.md for detailed documentation.

Keyboard Shortcuts

Key Action
Ctrl+K / Cmd+K Focus search
N New bookmark
? Show shortcuts help
↑ / ↓ Navigate search results
Enter Select result
Esc Close search/modal

Import/Export Formats

JSON Export/Import

  • Format: Linkwarden-compatible hierarchical collections
  • Fields: All metadata (title, description, meta_image, favicon, site name, type, author, keywords, locale, http_status, content_type, timestamps, tags, favorites)
  • Hierarchy: Categories are exported as collections with parent/child relationships
  • Favorites: Exported as pinnedLinks array
  • Import: Supports Linkwarden, Raindrop, and browser JSON formats

HTML Export/Import

  • Format: Netscape Bookmark File (browser standard)
  • Hierarchy: Full folder structure preserved (parent/child folders)
  • Attributes: ADD_DATE, LAST_MODIFIED, ICON, and descriptions included
  • Favorites: Exported as a special toolbar folder
  • Import: Nested folders are imported as hierarchical categories

CSV Export/Import

  • Format: Simple flat table
  • Fields: url, title, description, category, tags, is_favorite, created_at

Security Features

  • CSRF Protection: All forms include CSRF tokens
  • XSS Prevention: All output is escaped by default
  • SQL Injection Prevention: All queries use prepared statements
  • Password Hashing: Argon2id or bcrypt with secure defaults
  • Session Security: HTTPOnly cookies, secure flags, regeneration
  • Rate Limiting Ready: API endpoints support rate limiting headers

Performance Optimizations

  • Full-text Search: MySQL FULLTEXT indexes for fast search
  • File-based Caching: JSON cache for search results and metadata
  • Lazy Loading: Images and non-critical resources load lazily
  • Minimal Dependencies: No external PHP packages required
  • Client-side Caching: Search results cached in browser memory

Troubleshooting

Docker Issues

Containers won't start:

# Check container logs
docker compose logs -f

# Rebuild containers
docker compose down && docker compose up -d --build

Database connection issues in Docker:

  • Wait for MySQL to fully initialize (check with docker compose logs mysql)
  • Ensure the MySQL health check passes before the web container starts

General Issues

"500 Internal Server Error"

  • Check PHP error logs (in Docker: docker compose logs web)
  • Verify config.json syntax is valid
  • Ensure cache and logs directories are writable

"Database Connection Failed"

  • Verify database credentials in config.json
  • Check if MySQL server is running
  • Ensure database user has proper permissions

"Class Not Found"

  • Check namespace declarations match folder structure
  • Verify autoloader is properly included

Search Not Working

  • Ensure full-text indexes exist on bookmarks table
  • Check if minimum word length is configured in MySQL

License

MIT License - see LICENSE file for details.

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Submit a pull request

Docker Commands Reference

# Start containers
docker compose up -d

# Stop containers
docker compose down

# View logs
docker compose logs -f

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

# Access MySQL CLI
docker compose exec mysql mysql -u bookmark_user -pbookmark_pass bookmarks_db

# Access PHP container shell
docker compose exec web bash

Support

For issues and feature requests, please use the GitHub issue tracker.

About

A fast, modular bookmark management system built with PHP 8.2+ and MySQL. Features full-text search, nested categories, tagging, import/export, dark mode, GDPR compliance, and Docker support.

Resources

Stars

Watchers

Forks

Contributors