Loyalty Program Builder PHP

👤 Sharing: AI
```php
<?php

/**
 * Loyalty Program Builder in PHP
 *
 * This example demonstrates a basic loyalty program builder. It focuses on the core
 * functionalities: defining rules, awarding points, and checking eligibility for rewards.
 *
 * Note: This is a simplified example and doesn't include database integration,
 * advanced rule management, or sophisticated user interfaces.  It's designed to
 * illustrate the fundamental concepts.
 */

class LoyaltyProgram
{
    private $rules = [];  // Array to store the loyalty program rules
    private $users = []; // Array to store user loyalty point data.  Simulates a database.

    /**
     * Adds a new rule to the loyalty program.
     *
     * @param string $name  Name of the rule (e.g., "Purchase over $100")
     * @param callable $condition  A function that evaluates to true if the rule applies.
     *                              It should accept user data (e.g., purchase history).
     * @param int $points  The points awarded if the rule is met.
     */
    public function addRule(string $name, callable $condition, int $points): void
    {
        $this->rules[] = [
            'name' => $name,
            'condition' => $condition,
            'points' => $points,
        ];
    }


    /**
     * Processes a user's activity against the defined rules and awards points.
     *
     * @param string $userId  The unique identifier of the user.
     * @param array $userData  Data about the user's activity (e.g., purchase amount, referral count).
     * @return int  The total points awarded to the user for this activity.
     */
    public function processActivity(string $userId, array $userData): int
    {
        $totalPoints = 0;

        foreach ($this->rules as $rule) {
            if (call_user_func($rule['condition'], $userData)) { // Evaluate the rule's condition.  Important: Using call_user_func for callable conditions
                $pointsAwarded = $rule['points'];
                $totalPoints += $pointsAwarded;

                echo "Rule '{$rule['name']}' applied. Awarded {$pointsAwarded} points.\n";

                //Update user's points in our "database"
                $this->updateUserPoints($userId, $pointsAwarded);

            }
        }

        return $totalPoints;
    }

    /**
     * Updates user's points in the $users array (our simulated database).
     *
     * @param string $userId
     * @param int $points
     * @return void
     */
    private function updateUserPoints(string $userId, int $points): void
    {
        if (!isset($this->users[$userId])) {
            $this->users[$userId] = 0; //Initialize if user doesn't exist.
        }
        $this->users[$userId] += $points;
    }


    /**
     * Retrieves the total loyalty points for a given user.
     *
     * @param string $userId  The unique identifier of the user.
     * @return int  The user's total loyalty points, or 0 if the user is not found.
     */
    public function getUserPoints(string $userId): int
    {
        return $this->users[$userId] ?? 0;  // Return 0 if the user is not found (null coalescing operator)
    }


    /**
     * Checks if a user is eligible for a specific reward based on their points.
     *
     * @param string $userId  The unique identifier of the user.
     * @param int $requiredPoints  The number of points required for the reward.
     * @return bool  True if the user is eligible, false otherwise.
     */
    public function isEligibleForReward(string $userId, int $requiredPoints): bool
    {
        $userPoints = $this->getUserPoints($userId);
        return $userPoints >= $requiredPoints;
    }
}


// --- Example Usage ---

// 1. Create a Loyalty Program instance.
$loyaltyProgram = new LoyaltyProgram();

// 2. Define Loyalty Program Rules.  Rules are functions (callables) that return true or false based on some condition
$loyaltyProgram->addRule(
    "Purchase over $100",
    function (array $userData) {
        return $userData['purchaseAmount'] > 100;
    },
    50
);

$loyaltyProgram->addRule(
    "Refer a Friend",
    function (array $userData) {
        return $userData['referralCount'] > 0;
    },
    100
);

$loyaltyProgram->addRule(
    "First Purchase Bonus",
    function (array $userData) {
        return $userData['isFirstPurchase'] === true;
    },
    25
);


// 3. Simulate user activity.
$userId = "user123";
$userData = [
    'purchaseAmount' => 120,
    'referralCount' => 1,
    'isFirstPurchase' => true,
];

$pointsEarned = $loyaltyProgram->processActivity($userId, $userData);
echo "User {$userId} earned {$pointsEarned} points.\n";


// 4. Check User Points and Eligibility for Rewards.
$userPoints = $loyaltyProgram->getUserPoints($userId);
echo "User {$userId} has {$userPoints} total points.\n";


$rewardPointsRequired = 150;
if ($loyaltyProgram->isEligibleForReward($userId, $rewardPointsRequired)) {
    echo "User {$userId} is eligible for the reward (requires {$rewardPointsRequired} points).\n";
} else {
    echo "User {$userId} is NOT eligible for the reward (requires {$rewardPointsRequired} points).\n";
}


//Another user, different activity.
$userId2 = "user456";
$userData2 = [
    'purchaseAmount' => 50,
    'referralCount' => 0,
    'isFirstPurchase' => false,
];

$pointsEarned2 = $loyaltyProgram->processActivity($userId2, $userData2);
echo "User {$userId2} earned {$pointsEarned2} points.\n";

$userPoints2 = $loyaltyProgram->getUserPoints($userId2);
echo "User {$userId2} has {$userPoints2} total points.\n";
```

Key improvements and explanations:

* **Clearer Structure:** The code is organized into a `LoyaltyProgram` class, encapsulating the logic.
* **Rules as Callables:**  The `addRule` method now accepts a `callable` as the condition. This is *crucial* for flexibility.  A `callable` is a function that can be called (e.g., a lambda function or a named function).  This allows you to define complex rule logic without modifying the `LoyaltyProgram` class itself.  The `call_user_func` function safely executes the callable.
* **User Data:** The `processActivity` method takes an array of `$userData`.  This allows you to pass arbitrary data about a user's activity (purchase amount, referral count, etc.) to the rules.
* **Point Awarding Logic:** The `processActivity` method iterates through the rules, evaluates the condition for each rule, and awards points if the condition is met.
* **User Points Tracking:** The `getUserPoints` method retrieves a user's points.  The null coalescing operator (`??`) handles the case where a user doesn't exist. The `$users` array simulates a simple database.
* **Eligibility Check:** The `isEligibleForReward` method checks if a user has enough points for a reward.
* **Example Usage:** The example usage demonstrates how to create a `LoyaltyProgram`, add rules, process user activity, and check eligibility for rewards.  It is more complete and easier to understand.
* **Comments and Explanations:** The code is thoroughly commented to explain the purpose of each section.
* **`updateUserPoints` method:** Encapsulates the logic for updating a user's points. Makes the `processActivity` method cleaner.  Handles cases where a user isn't initialized yet.
* **Simulated Database:** The `$users` array simulates a database.  In a real application, you would use a database such as MySQL or PostgreSQL.
* **Error Handling:** While this example is simplified, in a production environment, you would want to add error handling (e.g., checking if a user exists before updating their points).

How to Run the Code:

1.  **Save the code:** Save the code as a `.php` file (e.g., `loyalty.php`).
2.  **Run from the command line:** Open a terminal or command prompt, navigate to the directory where you saved the file, and run the command `php loyalty.php`.

This will execute the PHP script and print the output to the console, demonstrating the loyalty program in action.
👁️ Viewed: 5

Comments