Lesson 95 – Implementing the Watchlist System with AJAX in Flipnzee Auctions


Series: Building the Flipnzee Auctions Plugin
Lesson: 95
Project: Flipnzee Auctions – A WordPress Auction Plugin for Websites & Digital Assets


Introduction

In the previous lesson, we designed the Watchlist feature for Flipnzee Auctions. The objective was to allow registered users to bookmark auctions they are interested in and easily revisit them later from a dedicated My Watchlist page.

This implementation transformed that design into a working feature by introducing a dedicated Watchlist Manager, AJAX-powered interactions, frontend buttons, and a Watchlist shortcode. As with many real-world development tasks, the implementation also involved extensive debugging and refinement to ensure the feature integrates correctly with the rest of the plugin.


Objectives

The primary objectives of this lesson were:

  • Implement a Watchlist Manager for database operations.
  • Allow logged-in users to add auctions to their watchlist.
  • Allow users to remove auctions from their watchlist.
  • Prevent duplicate watchlist entries.
  • Display a personalised Watchlist page.
  • Implement secure AJAX requests using WordPress nonces.
  • Integrate the Watchlist button into auction listings.

Files Added and Updated

New Components

  • includes/class-watchlist-manager.php
  • includes/class-watchlist-ajax.php
  • assets/js/watchlist.js

Updated Components

  • includes/class-shortcodes.php
  • flipnzee-auctions.php

Building the Watchlist Manager

A dedicated manager class was introduced to centralise all watchlist-related database operations.

Its responsibilities include:

  • Initialising database access.
  • Checking whether an auction already exists in a user’s watchlist.
  • Adding auctions.
  • Removing auctions.
  • Retrieving all saved auctions.
  • Counting the number of users watching an auction.

Separating these responsibilities into a dedicated class improves maintainability and follows the plugin’s object-oriented architecture.


Preventing Duplicate Entries

Before inserting a new record, the manager verifies whether the auction has already been saved.

Example:

if ( self::is_in_watchlist( $auction_id, $user_id ) ) {
	return true;
}

This ensures that repeated clicks do not create duplicate database entries.


AJAX Integration

Dedicated AJAX handlers were implemented for both watchlist actions.

The handlers perform:

  • Nonce verification
  • Login validation
  • Input sanitisation
  • Database updates
  • JSON success/error responses

This allows watchlist operations to be performed without navigating away from the current page.


Rendering the Watchlist Button

A reusable Watchlist button renderer was implemented.

Depending on the current state, it automatically displays:

❤ Add to Watchlist

or

❤ Remove from Watchlist

This state is determined dynamically by checking whether the current auction already exists in the logged-in user’s watchlist.


Creating the Watchlist Shortcode

A dedicated shortcode was implemented to display the user’s saved auctions.

The shortcode performs the following steps:

  • Retrieves the current user’s watchlist.
  • Loads each saved auction.
  • Retrieves the associated website listing.
  • Displays auction information.
  • Provides a link back to the listing.

Current output includes:

  • Listing title
  • Auction ID
  • Auction status
  • Current bid
  • Listing link

This provides users with a simple dashboard for managing their saved auctions.


Database Operations

The Watchlist Manager now supports:

  • Adding auctions
  • Removing auctions
  • Checking whether an auction is already saved
  • Retrieving all saved auctions
  • Counting watchers

These methods provide a reusable backend API for future watchlist-related features.


Security Considerations

Several WordPress security practices were implemented throughout this lesson.

These include:

  • Nonce verification using check_ajax_referer()
  • Login verification
  • Sanitising incoming POST values
  • Prepared SQL statements
  • Escaping frontend output
  • Using the WordPress database API

These measures help protect the feature against common attack vectors.


Debugging and Troubleshooting

A considerable portion of this lesson involved debugging and integration testing.

Issues encountered included:

  • Duplicate method declarations
  • Missing manager methods
  • PHP fatal errors
  • AJAX HTTP 500 errors
  • JavaScript event binding problems
  • Cached JavaScript during development
  • Leftover debugging statements
  • Plugin activation failures
  • Watchlist manager integration issues

Resolving these problems reinforced the importance of systematic debugging, incremental testing, and verifying both backend and frontend behaviour throughout development.


Current Functionality

The Watchlist feature now successfully:

  • Adds auctions to a user’s watchlist.
  • Removes auctions from a user’s watchlist.
  • Prevents duplicate entries.
  • Retrieves saved auctions.
  • Displays a personalised Watchlist page.
  • Uses secure AJAX communication.
  • Integrates with the auction interface.

Known Limitation

One frontend enhancement remains.

After adding or removing an auction using AJAX, the underlying database is updated correctly, but the visible page does not immediately reflect the change until the page is refreshed.

The backend functionality is fully operational. The remaining work is limited to improving frontend state synchronisation after successful AJAX requests.

This enhancement will be addressed during a future UI refactoring lesson.


Lessons Learned

This implementation highlighted several important software engineering practices:

  • Keep business logic separate from presentation.
  • Build reusable manager classes.
  • Secure every AJAX endpoint.
  • Prevent duplicate database records.
  • Validate all user input.
  • Test incrementally.
  • Use browser developer tools alongside server logs for debugging.
  • Separate backend functionality from frontend user experience improvements.

Download Source Code

Download the starting version of the plugin before the lesson:

Download the completed version after this lesson: 


Future Roadmap

The Watchlist system provides a strong foundation for several upcoming enhancements, including:

  • Instant UI updates after AJAX operations.
  • Reusable auction card rendering.
  • Watcher counters.
  • Email notifications.
  • Auction alerts.
  • User dashboard improvements.
  • Real-time watchlist interactions.

Conclusion

Lesson 95 marks another significant milestone in the development of Flipnzee Auctions.

The plugin now includes a functional Watchlist system that enables registered users to save auctions for future reference using secure AJAX-powered interactions.

Although a minor frontend synchronisation enhancement remains, the underlying architecture is complete, extensible, and ready to support future features such as notifications, live updates, and personalised auction management.


Git Commit

Lesson 95: Implement Watchlist system with AJAX, shortcode, and database manager

This lesson also reinforces an important principle of plugin development: building a reliable backend first creates a solid foundation upon which frontend enhancements can be safely and incrementally added.

Lesson 94 Implementation: Building a Dynamic AJAX Watchlist Toggle for Flipnzee Auctions

Lesson 94 Implementation: Building a Dynamic AJAX Watchlist Toggle for Flipnzee Auctions

In the previous lesson, the Flipnzee Auctions plugin introduced the foundation of the Watchlist feature, allowing authenticated users to add auctions to their personal watchlists using AJAX. While the backend functionality was working correctly, the user experience still required significant refinement.

The Watchlist button always displayed “Add to Watchlist”, regardless of whether the auction had already been added to the user’s watchlist. Furthermore, there was no support for removing auctions from the watchlist using the same interface.

Lesson 94 focused on transforming the Watchlist into a fully interactive feature by introducing a dynamic AJAX-powered toggle button that automatically switches between Add to Watchlist and Remove from Watchlist while keeping the user interface synchronized with the database.


Lesson Objectives

The primary objectives of this lesson were:

  • Display the correct Watchlist state when an auction page loads.
  • Determine whether an auction is already present in the logged-in user’s watchlist.
  • Convert the Watchlist button into a dynamic toggle.
  • Support both Add and Remove operations using AJAX.
  • Update the interface instantly without refreshing the page.
  • Improve the user experience.
  • Refactor the JavaScript implementation for improved readability.
  • Display the Watchlist feature only to authenticated users.

Reviewing the Existing Watchlist

Before beginning this lesson, the plugin already supported:

  • Watchlist database table
  • AJAX Add to Watchlist
  • Duplicate entry prevention
  • Watchlist Manager
  • Watchlist AJAX Controller
  • Nonce verification
  • Logged-in user validation

However, every auction page still displayed the same button:

❤ Add to Watchlist

even when the auction had already been added by the current user.


Rendering the Correct Initial State

The first improvement was made within the Watchlist Manager.

Instead of rendering a fixed button, the plugin now determines whether the current auction already exists in the logged-in user’s watchlist.

$is_watchlisted = self::is_in_watchlist(
	$auction_id,
	get_current_user_id()
);

Based on the result, the button is rendered appropriately.

When the auction is already being watched:

❤ Remove from Watchlist

Otherwise:

❤ Add to Watchlist

This ensures that the user interface accurately reflects the database before any JavaScript is executed.


Restricting the Watchlist to Logged-in Users

During testing, an important usability issue was discovered.

Anonymous visitors could still see the Watchlist button even though the feature required authentication. Clicking the button initiated an AJAX request that ultimately failed because the visitor was not logged in.

Instead of presenting a button that anonymous visitors could not use, the implementation was simplified by rendering the Watchlist button only for authenticated users.

A guard clause was introduced near the beginning of the rendering method.

if ( ! is_user_logged_in() ) {
	return;
}

This approach provides several advantages:

  • Eliminates unnecessary AJAX requests
  • Prevents user confusion
  • Simplifies the interface
  • Improves overall user experience

Future versions of the plugin may replace the hidden button with a dedicated “Log in to use Watchlist” link or notification, but the current implementation provides a cleaner experience for both visitors and registered users.


Using a CSS Class to Track State

Rather than maintaining additional JavaScript variables, the Watchlist button itself became the source of truth.

If an auction already exists in the user’s watchlist, the rendered button receives the CSS class:

watchlisted

The JavaScript simply checks:

const isWatchlisted = button.hasClass( 'watchlisted' );

This eliminates unnecessary complexity while keeping the implementation easy to understand.


Selecting the Appropriate AJAX Action

Instead of maintaining separate click handlers for adding and removing auctions, Lesson 94 introduced a single dynamic toggle.

The JavaScript determines which AJAX action should be executed.

const ajaxAction = isWatchlisted
	? 'flipnzee_remove_from_watchlist'
	: 'flipnzee_add_to_watchlist';

The same button can now perform both operations without duplicating code.


Completing the Remove Watchlist AJAX Handler

While Lesson 93 implemented the Add to Watchlist functionality, Lesson 94 completed the remaining AJAX workflow for removing auctions.

The Remove handler performs the same security validations as the Add handler.

These include:

  • Nonce verification
  • Logged-in user validation
  • Auction ID validation
  • Database deletion
  • JSON success or error response

Maintaining identical validation logic for both operations keeps the AJAX architecture consistent throughout the plugin.


Updating the Interface Without Reloading

One of the most visible improvements introduced during this lesson was updating the button immediately after a successful AJAX request.

When an auction is added:

button
	.addClass( 'watchlisted' )
	.text( '❤ Remove from Watchlist' );

When removed:

button
	.removeClass( 'watchlisted' )
	.text( '❤ Add to Watchlist' );

Users now receive immediate visual feedback without refreshing the page.


Refactoring the JavaScript

Throughout development, several temporary debugging statements were introduced while troubleshooting AJAX requests, browser caching, and response handling.

After verifying that the implementation worked correctly, all temporary debugging code was removed.

The resulting JavaScript became considerably cleaner.

The overall workflow now follows a simple sequence:

  1. User clicks the Watchlist button.
  2. Determine current Watchlist state.
  3. Select the appropriate AJAX action.
  4. Send the AJAX request.
  5. Update the button after a successful response.

Keeping the implementation concise improves readability while making future maintenance much easier.


Development Challenges

Lesson 94 proved to be one of the most educational lessons completed so far.

During implementation several issues had to be investigated, including:

  • Browser caching of JavaScript files
  • AJAX response validation
  • Logged-out user behavior
  • Dynamic button rendering
  • JavaScript refactoring
  • Watchlist state synchronization

Rather than attempting to continuously patch the implementation, the project was rolled back to the stable Lesson 93 Git tag.

The feature was then rebuilt incrementally, validating every small improvement before introducing the next enhancement.

This iterative approach produced a significantly cleaner and more reliable implementation.


Lessons Learned

Several valuable software engineering principles were reinforced during this lesson.

Build on Stable Foundations

Rolling back to a known working version proved much more efficient than attempting to repair increasingly complex code.

Version control once again demonstrated its importance throughout the development process.


Small Changes Reduce Complexity

Implementing one improvement at a time made debugging significantly easier.

Small, testable changes reduced uncertainty while simplifying troubleshooting.


Use Guard Clauses

Introducing an early return for anonymous visitors simplified the rendering logic.

Instead of nesting multiple conditional statements, the method now exits immediately whenever the user is not authenticated.

This improves readability while reducing unnecessary processing.


Separate Responsibilities

The Watchlist implementation now follows clear architectural boundaries.

Watchlist Manager

  • Business logic
  • Database operations
  • Button rendering

Watchlist AJAX Controller

  • AJAX request processing
  • Security validation
  • JSON responses

watchlist.js

  • User interaction
  • AJAX communication
  • Dynamic interface updates

This separation will simplify future enhancements.


User Experience Is Just As Important

Although the backend functionality already existed, the feature felt incomplete until the interface accurately reflected user actions.

Small improvements to user experience often have a significant impact on the perceived quality of software.


Testing

After completing the implementation, the following functionality was successfully verified.

Logged-in Users

  • Add to Watchlist
  • Remove from Watchlist
  • Dynamic button updates
  • Correct initial Watchlist state
  • AJAX communication
  • Database synchronization
  • Duplicate prevention

Logged-out Visitors

  • Watchlist button no longer displayed
  • No unnecessary AJAX requests
  • Cleaner interface
  • Consistent user experience

Looking Ahead

With the Watchlist now functioning as a complete AJAX-powered toggle, the Flipnzee Auctions plugin continues moving toward a production-ready auction platform.

Possible future enhancements include:

  • My Watchlist page
  • Watchlist shortcode
  • User dashboard integration
  • Email notifications
  • Auction ending reminders
  • Watchlist statistics
  • Login prompt for anonymous visitors
  • Gutenberg block integration

Download Source Code

Download the starting version of the plugin before the lesson:

Download the completed version after this lesson:


Conclusion

Lesson 94 transformed the Watchlist from a basic AJAX feature into a polished and user-friendly component of the Flipnzee Auctions plugin.

Users can now seamlessly add and remove auctions from their watchlists using a single dynamic button that accurately reflects the current state without requiring a page refresh.

The lesson also reinforced the value of incremental development, disciplined debugging, clean architecture, and thoughtful user experience design. By introducing authenticated rendering, dynamic state management, and cleaner frontend logic, the Watchlist has become a much more intuitive and maintainable feature.

As Flipnzee Auctions continues to evolve, these development practices will remain essential for building a stable, professional, and extensible WordPress auction platform.

Lesson 93: AJAX-Based Watchlist Functionality

Introduction

With the backend Watchlist Manager completed in the previous lesson, the next step is to make the feature interactive. Rather than forcing users to reload the page after adding or removing an auction from their watchlist, we will implement AJAX-powered interactions that provide a smoother and more responsive user experience.

In this lesson, we will connect the Watchlist Manager to WordPress AJAX handlers, enabling logged-in users to add and remove auctions from their watchlist with a single click while maintaining proper security through nonce verification and permission checks.


Learning Objectives

By the end of this lesson, we will:

  • Register custom WordPress AJAX actions.
  • Implement secure AJAX request handlers.
  • Validate logged-in users.
  • Verify WordPress nonces.
  • Connect AJAX handlers to the Watchlist Manager.
  • Return JSON success and error responses.
  • Prepare the plugin for frontend watchlist buttons.

Why AJAX?

Without AJAX, every click on Add to Watchlist would require a full page reload.

Using AJAX provides several advantages:

  • Faster user interactions.
  • Better user experience.
  • Reduced server load.
  • Cleaner interface.
  • Immediate feedback after each action.

This approach aligns with the behavior users expect from modern auction and e-commerce platforms.


Planned Files

The following files will be created or updated:

flipnzee-auctions.php

includes/class-watchlist-manager.php

includes/class-watchlist-ajax.php

assets/js/watchlist.js

New AJAX Class

A dedicated class will be introduced:

Flipnzee_Watchlist_Ajax

This class will keep all AJAX functionality separate from the Watchlist Manager, maintaining a clean separation between business logic and request handling.


Planned Methods

The new AJAX class will include methods such as:

register_hooks()

add_watchlist()

remove_watchlist()

validate_request()

Each method will have a single responsibility, making the code easier to understand and maintain.


AJAX Workflow

The request lifecycle will be:

User clicks
"Add to Watchlist"
          │
          ▼
JavaScript AJAX Request
          │
          ▼
WordPress AJAX Handler
          │
          ▼
Nonce Verification
          │
          ▼
User Authentication
          │
          ▼
Watchlist Manager
          │
          ▼
Database
          │
          ▼
JSON Response
          │
          ▼
Frontend Updates Button

The same workflow will be used when removing an auction from the watchlist.


Security Considerations

Every AJAX request will be protected by:

  • WordPress nonces.
  • Logged-in user verification.
  • Integer validation using absint().
  • JSON responses via wp_send_json_success() and wp_send_json_error().
  • Proper capability and permission checks where appropriate.

These measures help protect the feature against unauthorized or malformed requests.


JavaScript Responsibilities

A dedicated JavaScript file will:

  • Detect button clicks.
  • Send AJAX requests.
  • Handle loading states.
  • Update button text without refreshing the page.
  • Display success or error messages.

Keeping frontend behavior in a separate script improves maintainability and organization.


Testing Plan

During implementation we will verify:

  • Logged-out users cannot modify watchlists.
  • Logged-in users can successfully add auctions.
  • Logged-in users can remove auctions.
  • Duplicate watchlist entries are prevented.
  • JSON responses are returned correctly.
  • Nonce validation blocks invalid requests.
  • Database records are inserted and deleted as expected.
  • Button state updates correctly after each action.

Expected Outcome

By the end of this lesson, the Flipnzee Auctions plugin will support fully functional AJAX-powered watchlist operations. Users will be able to add or remove auctions from their watchlist instantly, without reloading the page, while the plugin maintains secure request handling and a clean separation between frontend interactions, AJAX processing, and backend business logic.


Planned Git Commit

Lesson 93: Implement AJAX watchlist handlers and secure user interactions

This lesson bridges the gap between the backend Watchlist Manager created in Lesson 92 and the user-facing watchlist interface, laying the groundwork for a seamless and responsive auction experience.

Lesson 92 Implementation: Building the Watchlist Manager Class

Introduction

After creating the Watchlist database table and integrating it into the database migration framework in the previous lesson, the next logical step was to implement the backend component responsible for interacting with that table.

In this lesson, I developed a dedicated Watchlist Manager class that centralizes all watchlist-related database operations. Rather than scattering SQL queries throughout the plugin, all watchlist functionality is now encapsulated in a single class, following a modular and maintainable architecture.


Objectives

The primary objectives of this lesson were:

  • Create a dedicated Watchlist Manager class.
  • Load the new class into the plugin.
  • Initialize database resources efficiently.
  • Add auctions to a user’s watchlist.
  • Prevent duplicate watchlist entries.
  • Remove auctions from the watchlist.
  • Retrieve all watchlisted auctions for a user.
  • Count how many users are watching an auction.
  • Follow WordPress database API best practices.

Files Modified

includes/class-watchlist-manager.php

flipnzee-auctions.php

Step 1: Created the Watchlist Manager Class

A new class was introduced to isolate all watchlist-related functionality.

class Flipnzee_Watchlist_Manager {

}

This provides a dedicated location for all future watchlist business logic and keeps responsibilities clearly separated from other plugin components.


Step 2: Loaded the Class

The new class was registered in the plugin bootstrap so it is automatically available throughout the plugin.

require_once FLIPNZEE_AUCTION_PATH .
    'includes/class-watchlist-manager.php';

This follows the same loading approach used by the rest of the plugin.


Step 3: Added Initialization Logic

Instead of repeatedly accessing the database connection and table name throughout every method, an initialization method was implemented.

public static function init() {

    global $wpdb;

    self::$wpdb = $wpdb;

    self::$table = $wpdb->prefix . 'flipnzee_watchlist';

}

This reduces code duplication and centralizes the database configuration.


Step 4: Implemented add_to_watchlist()

The first functional method inserts an auction into a user’s watchlist.

public static function add_to_watchlist(
    $auction_id,
    $user_id
)

Before inserting a new record, the method verifies that the auction has not already been added by the same user.

The insertion uses WordPress’s database API:

self::$wpdb->insert()

instead of manually writing SQL.


Step 5: Implemented is_in_watchlist()

To prevent duplicate records, a lookup method was added.

public static function is_in_watchlist(
    $auction_id,
    $user_id
)

The method executes a prepared SQL query and returns a boolean value indicating whether a matching watchlist entry already exists.

Prepared statements ensure the query is secure against SQL injection.


Step 6: Implemented remove_from_watchlist()

Removing a watchlist entry is now handled by a dedicated method.

public static function remove_from_watchlist(
    $auction_id,
    $user_id
)

The implementation uses:

self::$wpdb->delete()

which follows WordPress coding standards and safely deletes matching records.


Step 7: Implemented get_user_watchlist()

A retrieval method was added to fetch all auctions saved by a particular user.

public static function get_user_watchlist(
    $user_id
)

The query returns an associative array ordered by the date the auctions were added to the watchlist.

This method will later power the My Watchlist page and shortcode.


Step 8: Implemented count_watchers()

The final method counts how many users are watching a particular auction.

public static function count_watchers(
    $auction_id
)

This functionality will later be used to display auction popularity and provide additional engagement metrics.


Security Considerations

Throughout the implementation, WordPress database best practices were followed.

These include:

  • Using $wpdb->prepare() for dynamic SQL queries.
  • Sanitizing IDs with absint().
  • Using $wpdb->insert() instead of raw INSERT statements.
  • Using $wpdb->delete() instead of raw DELETE statements.
  • Returning consistent boolean or integer values.

These practices improve both security and maintainability.


Class Structure

By the end of the lesson, the Watchlist Manager contains the following methods:

Flipnzee_Watchlist_Manager
│
├── init()
├── add_to_watchlist()
├── is_in_watchlist()
├── remove_from_watchlist()
├── get_user_watchlist()
└── count_watchers()

This centralized architecture keeps all watchlist logic in one place and makes future enhancements significantly easier.


Testing Performed

The implementation was validated by:

  • Creating the new manager class.
  • Successfully loading the class into the plugin.
  • Verifying PHP syntax after each development step.
  • Ensuring the class initialized correctly.
  • Confirming all database helper methods compiled successfully.
  • Reviewing each database query for correctness.
  • Ensuring all SQL operations use WordPress database APIs.

Challenges Encountered

During development, careful attention was given to designing a reusable architecture rather than embedding SQL throughout the plugin.

Several design decisions were made to improve long-term maintainability:

  • Centralizing database access in a single class.
  • Avoiding duplicate watchlist entries.
  • Using prepared statements for all SELECT queries.
  • Leveraging WordPress helper methods for INSERT and DELETE operations.
  • Keeping each method focused on a single responsibility.

This approach makes future debugging and feature development much easier.


Lessons Learned

This lesson reinforced several important WordPress development principles:

  • Business logic should be separated from presentation logic.
  • Database operations are easier to maintain when encapsulated in dedicated manager classes.
  • WordPress database helper methods improve readability and security.
  • Reusable methods reduce duplication and simplify future development.
  • Designing extensible backend components early provides a strong foundation for upcoming AJAX and frontend features.

Download Source Code

Download the starting version of the plugin before the lesson:

Download the completed version after this lesson:


Outcome

At the end of this lesson, the Flipnzee Auctions plugin now includes a fully functional Watchlist Manager responsible for all backend watchlist operations. The class provides secure, reusable methods for adding, removing, retrieving, and counting watchlist entries while keeping the plugin architecture clean and modular.

This backend service establishes the foundation for the next phase of development, where the watchlist functionality will be connected to AJAX endpoints and integrated into the user interface for a seamless user experience.

Lesson 92: Building the Watchlist Manager Class

Introduction

With the Watchlist database table successfully added in the previous lesson, the next step is to build the business logic that interacts with it. Rather than allowing different parts of the plugin to access the database directly, we will create a dedicated Watchlist Manager class responsible for handling all watchlist-related operations.

This approach follows the plugin’s modular architecture, keeping database queries centralized, reusable, and easier to maintain.


What You Will Learn

In this lesson, you will learn how to:

  • Create a dedicated Watchlist Manager class.
  • Organize watchlist-related database operations.
  • Add and remove auctions from a user’s watchlist.
  • Check whether an auction is already in a watchlist.
  • Retrieve a user’s watchlisted auctions.
  • Follow WordPress database best practices using $wpdb.
  • Keep business logic separate from presentation code.

Why This Lesson Matters

Although the Watchlist table now exists, it currently has no way to interact with the rest of the plugin.

Instead of writing SQL queries throughout the plugin, we’ll encapsulate all watchlist functionality inside a single class.

This provides several advantages:

  • Cleaner code organization
  • Easier debugging
  • Better code reuse
  • Improved security
  • Easier future maintenance

Planned Features

By the end of this lesson, the new manager class will support methods such as:

add_to_watchlist()

remove_from_watchlist()

is_in_watchlist()

get_user_watchlist()

count_watchers()

Each method will perform one specific task, making the class simple and easy to extend.


Proposed File Structure

A new file will be introduced:

includes/
├── class-watchlist-manager.php

The loader will also be updated so the class is automatically available throughout the plugin.


Planned Class Structure

Flipnzee_Watchlist_Manager
│
├── add_to_watchlist()
├── remove_from_watchlist()
├── is_in_watchlist()
├── get_user_watchlist()
└── count_watchers()

Expected Workflow

When a user clicks Add to Watchlist, the flow will eventually become:

User clicks "Add to Watchlist"
            │
            ▼
Watchlist Manager
            │
            ▼
Validate User
            │
            ▼
Check Duplicate Entry
            │
            ▼
Insert into Database
            │
            ▼
Return Success

Likewise, removing an auction will simply delete the corresponding database record while maintaining data integrity.


Best Practices Covered

Throughout this lesson, we’ll follow several WordPress development best practices:

  • Use prepared SQL statements.
  • Sanitize all user input.
  • Prevent duplicate watchlist entries.
  • Return consistent boolean or array results.
  • Keep database logic inside one dedicated class.
  • Maintain compatibility with future AJAX and REST API integrations.

Outcome

At the end of this lesson, the Flipnzee Auctions plugin will have a fully functional Watchlist Manager class capable of handling all watchlist database operations. This will provide the core backend functionality needed before implementing the user interface, AJAX interactions, and frontend watchlist features in the upcoming lessons.

Lesson 91: Auction Watchlist (Favorite Auctions)


Project: Flipnzee Auctions Plugin

Lesson: 91

Topic: Building a User Watchlist (Favorite Auctions) System


Introduction

As the number of auctions grows, users need an easy way to keep track of listings they are interested in without placing a bid immediately. A watchlist (or favorites) feature allows registered users to bookmark auctions and quickly revisit them later.

In this lesson, we will implement a complete auction watchlist system, enabling users to add and remove auctions from their personal watchlist. This feature improves user engagement and lays the foundation for future enhancements such as watchlist email notifications, price drop alerts, and ending-soon reminders.


Learning Objectives

By the end of this lesson, we will:

  • Design a user watchlist system.
  • Create a dedicated database table for watchlists.
  • Register the watchlist through the migration framework.
  • Add “Add to Watchlist” and “Remove from Watchlist” functionality.
  • Prevent duplicate watchlist entries.
  • Secure AJAX requests using WordPress nonces.
  • Display watchlist status on auction pages.
  • Prepare for future notification features.

Why This Feature?

Many successful auction platforms provide a watchlist because users often discover auctions long before they are ready to bid.

Benefits include:

  • Better user engagement.
  • Higher return visitor rate.
  • Easier auction discovery.
  • Foundation for automated notifications.
  • Personalized user experience.

Database Design

A new table will be introduced:

wp_flipnzee_watchlist

Suggested structure:

ColumnTypeDescription
idBIGINTPrimary key
auction_idBIGINTAuction/Post ID
user_idBIGINTWordPress User ID
created_atDATETIMEDate added

Unique constraint:

(user_id, auction_id)

to prevent duplicate entries.


Files Planned

flipnzee-auctions.php

includes/class-database.php

includes/class-database-migration.php

includes/class-watchlist.php

includes/class-ajax.php

templates/

assets/js/frontend.js

assets/css/frontend.css

Features to Build

Part 1

Database migration for watchlist table.


Part 2

Watchlist manager class.


Part 3

Add to Watchlist button.


Part 4

Remove from Watchlist button.


Part 5

AJAX handlers.


Part 6

Nonce verification.


Part 7

Display watchlist status.


Part 8

User watchlist page shortcode.


Testing Plan

We will verify:

  • Logged-out users cannot use watchlists.
  • Logged-in users can add auctions.
  • Duplicate entries are prevented.
  • Removing items works.
  • AJAX responses are secure.
  • Database records are correctly created and deleted.
  • Migration executes successfully on upgrades.

Expected Outcome

By the end of Lesson 91, Flipnzee Auctions will include a complete watchlist system that enables users to save favorite auctions for later viewing. The feature will integrate cleanly with the database migration framework introduced in Lesson 90 and provide a strong foundation for future engagement features such as notifications, reminders, and personalized dashboards.


Git Commit (planned)

Lesson 91: Implement auction watchlist system with database migration

I think this is a natural progression from Lesson 90 because it immediately puts your new migration framework to practical use by introducing a new database table and a user-facing feature that will enhance the overall auction experience.