_binary From d71c7182d4dbc98e59bcf6712fb4a5eca2f02b7d Mon Sep 17 00:00:00 2001
From: Sujith Kakarlapudi <sujith.kakarlapudi@sjsu.edu>
Date: Tue, 4 Mar 2025 09:29:55 -0800
Subject: [PATCH] Test Data for Impressions in Yioop- New Method

---
 src/models/GroupModel.php      |   6 +-
 src/models/ImpressionModel.php |  28 +++++---
 tests/ManyUserExperiment.php   | 115 +++++++++++++++++++++++++++++++++
 3 files changed, 139 insertions(+), 10 deletions(-)

diff --git a/src/models/GroupModel.php b/src/models/GroupModel.php
index 8d7d0f419..283c60139 100644
--- a/src/models/GroupModel.php
+++ b/src/models/GroupModel.php
@@ -263,12 +263,14 @@ class GroupModel extends Model implements MediaConstants
      *      live before they expire and are deleted
      * @param int $encryption 0 means don't encrypt group, 1 means encrypt
      *      group
+     * @param boolean $skip_impression false means call intiWithDb, true means
+     *      dont call intiWithDb
      * @return int id of group added
      */
     public function addGroup($group_name, $user_id, $wiki_editors,
         $register = C\REQUEST_JOIN, $member = C\GROUP_READ,
         $voting = C\NON_VOTING_GROUP, $post_lifetime = C\FOREVER,
-        $encryption = 0)
+        $encryption = 0, $skip_impression = false)
     {
         $db = $this->db;
         $private_db = $this->private_db;
@@ -290,10 +292,12 @@ class GroupModel extends Model implements MediaConstants
             JOIN_DATE) VALUES
             ($user_id, $last_id, " . C\ACTIVE_STATUS . ", $now)";
         $db->execute($sql);
+        if ($skip_impression == false) {
         ImpressionModel::initWithDb($user_id, $last_id, C\GROUP_IMPRESSION,
             $db);
         ImpressionModel::initWithDb(C\PUBLIC_GROUP_ID, $last_id,
             C\GROUP_IMPRESSION, $db);
+        }
         if ($encryption != 0) {
             $sql = "INSERT INTO TYPE_KEYS (TYPE_ID, KEY_NAME) VALUES (?, ?)";
             //AES 256 is 32 bytes long (8*32 bits)
diff --git a/src/models/ImpressionModel.php b/src/models/ImpressionModel.php
index 3807e959c..5f394bdd9 100644
--- a/src/models/ImpressionModel.php
+++ b/src/models/ImpressionModel.php
@@ -81,7 +81,9 @@ class ImpressionModel extends Model
      */
     public function add($user_id, $item_id, $type_id)
     {
-        $this->addWithDb($user_id, $item_id, $type_id, $this->db);
+        $input_timestamp = time();
+        $this->addWithDb($user_id, $item_id, $type_id, $this->db,
+        $input_timestamp);
     }
     /**
      * Used to add a count record related to a web search to the impression
@@ -113,8 +115,9 @@ class ImpressionModel extends Model
             $this->initWithDb(C\PUBLIC_USER_ID, $db->insertID("QUERY_ITEM"),
                 $impression_type, $db);
         } else {
+            $input_timestamp = time();
             $this->addWithDb(C\PUBLIC_USER_ID, $row['ID'],
-                $impression_type, $db);
+                $impression_type, $db, $input_timestamp);
         }
     }
     /**
@@ -150,8 +153,9 @@ class ImpressionModel extends Model
             $this->initWithDb(C\PUBLIC_USER_ID, $db->insertID("QUERY_ITEM"),
                 C\QUERY_IMPRESSION_EXIT, $db);
         } else {
+            $input_timestamp = time();
             $this->addWithDb(C\PUBLIC_USER_ID, $row['ID'],
-                C\QUERY_IMPRESSION_EXIT, $db);
+                C\QUERY_IMPRESSION_EXIT, $db, $input_timestamp);
         }
     }
     /**
@@ -496,7 +500,8 @@ class ImpressionModel extends Model
         $num_views, $fuzzy_num_views)
     {
             $sql = "UPDATE ITEM_IMPRESSION_STAT SET FUZZY_NUM_VIEWS=?,
-                NUM_VIEWS=? WHERE ITEM_ID=? AND ITEM_TYPE=? AND UPDATE_PERIOD=?";
+                NUM_VIEWS=? WHERE ITEM_ID=? AND ITEM_TYPE=? AND
+                UPDATE_PERIOD=?";
             $parameters = [$fuzzy_num_views, $num_views, $item_id,
                 $item_type, $period];
             $result = $this->db->execute($sql, $parameters);
@@ -557,7 +562,8 @@ class ImpressionModel extends Model
             (?, ?, ?, " . C\FOREVER .", 0, 0, -1, -1)";
         $sql = $db->insertIgnore($sql, $dbinfo);
         $db->execute($sql, [C\PUBLIC_USER_ID, $item_id, $type_id]);
-        self::addWithDb($user_id, $item_id, $type_id, $db);
+        $input_timestamp = time();
+        self::addWithDb($user_id, $item_id, $type_id, $db, $input_timestamp);
     }
     /**
      * Used to add a count record related to a particular user for a particular
@@ -575,20 +581,24 @@ class ImpressionModel extends Model
      * @param object $db a DatasourceManager used to query the Yioop
      *      Yioop database
      */
-    public static function addWithDb($user_id, $item_id, $type_id, $db)
+    public static function addWithDb($user_id, $item_id, $type_id, $db,
+    $input_timestamp)
     {
         if (!C\GROUP_ANALYTICS_MODE || C\GROUP_ANALYTICS_MODE == "0" ||
             !is_numeric($user_id) || !is_numeric($item_id)) {
             return;
         }
+        $current_time = $input_timestamp;
+        $current_time = ($current_time > 0) ? $current_time : time();
         $dbinfo = ["DBMS" => C\DBMS, "DB_HOST" => C\DB_HOST,
             "DB_USER" => C\DB_USER, "DB_PASSWORD" => C\DB_PASSWORD,
             "DB_NAME" => C\DB_NAME];
         $sql = "INSERT INTO ITEM_IMPRESSION VALUES (?, ?, ?, ?)";
         if ($user_id != C\PUBLIC_USER_ID) {
-            $db->execute($sql, [$user_id, $item_id, $type_id, time()]);
+            $db->execute($sql, [$user_id, $item_id, $type_id, $current_time]);
         }
-        $db->execute($sql, [C\PUBLIC_USER_ID, $item_id, $type_id, time()]);
+        $db->execute($sql, [C\PUBLIC_USER_ID, $item_id, $type_id,
+        $current_time]);
         $sql = "DELETE FROM ITEM_IMPRESSION_SUMMARY
             WHERE USER_ID=? AND ITEM_ID=? AND ITEM_TYPE=? AND UPDATE_PERIOD = ".
             C\MOST_RECENT_VIEW;
@@ -596,7 +606,7 @@ class ImpressionModel extends Model
         $sql = "INSERT INTO ITEM_IMPRESSION_SUMMARY VALUES
             (?, ?, ?, " . C\MOST_RECENT_VIEW .", ?, 0, -1, -1)";
         $sql = $db->insertIgnore($sql, $dbinfo);
-        $db->execute($sql, [$user_id, $item_id, $type_id, time()]);
+        $db->execute($sql, [$user_id, $item_id, $type_id, $current_time]);
         $sql = "UPDATE ITEM_IMPRESSION_SUMMARY
             SET NUM_VIEWS = NUM_VIEWS + 1 WHERE USER_ID=? AND
             ITEM_ID=? AND ITEM_TYPE=? AND UPDATE_PERIOD = ". C\FOREVER . "
diff --git a/tests/ManyUserExperiment.php b/tests/ManyUserExperiment.php
index 56a3994cc..39270e50f 100644
--- a/tests/ManyUserExperiment.php
+++ b/tests/ManyUserExperiment.php
@@ -36,6 +36,7 @@ namespace seekquarry\yioop\tests;
 use seekquarry\yioop\configs as C;
 use seekquarry\yioop\library as L;
 use seekquarry\yioop\models as M;
+use seekquarry\yioop\models\ImpressionModel;
 
 if (isset($_SERVER['DOCUMENT_ROOT']) && strlen($_SERVER['DOCUMENT_ROOT']) > 0) {
     echo "BAD REQUEST";
@@ -382,3 +383,117 @@ for ($i = 0; $i < C\ME_NUM_USERS; $i++) {
             C\RESOURCE_IMPRESSION);
     }
 }
+//New testing approach to create test data at randon timestamps
+$impression_model = new M\ImpressionModel();
+$user_ids = [];
+for ($i = 0; $i < C\ME_NUM_USERS; $i++) {
+    echo "Adding User $i\n";
+    $id = $user_model->addUser("User$i", "test", "First$i", "Last$i",
+        "user$i@email.net", C\ACTIVE_STATUS);
+    if ($id === false) {
+        echo "Problem inserting user into DB, aborting...\n";
+        exit(1);
+    }
+    $personal_group_name = C\PERSONAL_GROUP_PREFIX . $id;
+    if ($group_model->getGroupId($personal_group_name) < 0) {
+        $group_model->addGroup($personal_group_name,
+            $id, ["User$i"], C\INVITE_ONLY_JOIN, C\ACTIVE_STATUS,
+            C\NON_VOTING_GROUP, C\FOREVER, 0, true);
+    }
+    $user_ids[$i] = $id;
+}
+// add lots of groups
+$group_ids = [];
+for ($i = 0; $i < C\ME_NUM_GROUPS; $i++) {
+    echo "Creating Group $i\n";
+    $group_ids[$i] = $group_model->addGroup("Group$i", $user_ids[$i],["User$i"],
+      C\PUBLIC_JOIN, C\GROUP_READ_WIKI, C\NON_VOTING_GROUP, C\FOREVER,
+    0, true);
+}
+// add lots of users to groups (everyone belongs to at least group 1)
+for ($i = 0; $i < C\ME_NUM_USERS; $i++) {
+    $user_id = $user_ids[$i];
+    for ($j = 1; $j < ($i/100) + 1; $j++) {
+        if ($j != $i) {//by above user $i is owner (and so in) group $i
+            echo "Adding User $i (user id $user_id) to ".
+                "Group $j (group id {$group_ids[$j]})\n";
+            $group_model->addUserGroup($user_id, $group_ids[$j],
+                C\ACTIVE_STATUS);
+        }
+    }
+}
+class ManyUserExperiment extends ImpressionModel
+{
+    /**
+    * Fetches and processes user-group relationships, and associates groups
+    * with pages in the system.
+    *
+    * This function performs the following tasks:
+    * 1. Retrieves unique USER_IDs and GROUP_IDs from the USER_GROUP table,
+    * excluding specific USER_IDs and GROUP_IDs.
+    * 2. Collects a list of unique GROUP_IDs and USER_IDs.
+    * 3. Fetches PAGE_IDs associated with the unique GROUP_IDs
+    * from the GROUP_PAGE table.
+    * 4. Generates random timestamps within the past year.
+    * 5. For each unique USER_ID, associates them with each PAGE_ID
+    * by calling the `addWithDb` function, passing the appropriate parameters
+    * including a random timestamp.
+    * 6. Logs the additions to the database for debugging and tracking purposes.
+    *
+    * This function is designed to populate the system with test data by
+    * associating users with group pages, creating impressions.
+    *
+    */
+
+    public function addTestData()
+    {
+        $db = $this->db;
+        $user_group_list = [];
+        $group_id_list = [];
+        $unique_user_id_list = [];
+        /*
+           Here we exclude the root user ID and public user ID
+           while adding the test data
+         */
+        $sql_user_group_query = "SELECT USER_ID, GROUP_ID FROM USER_GROUP WHERE
+        USER_ID NOT IN (1, 2) AND GROUP_ID != 2";
+        $result_user_group_query = $db->execute($sql_user_group_query);
+        while ($row = $db->fetchArray($result_user_group_query)) {
+            $user_group_list[] = ['user_id' => $row['USER_ID'],
+            'group_id' => $row['GROUP_ID']];
+            $group_id_list[] = $row['GROUP_ID'];
+            $unique_user_id_list[] = $row['USER_ID'];
+        }
+        $unique_user_id_list = array_unique($unique_user_id_list);
+        $unique_group_id_list = array_unique($group_id_list);
+        $page_id_list = [];
+        if (!empty($unique_group_id_list)) {
+            $chunked_group_id_list = array_chunk($unique_group_id_list, 100);
+            foreach ($chunked_group_id_list as $chunk) {
+                $placeholders = implode(',', array_fill(0, count($chunk), '?'));
+                $sql_group_page_query = "SELECT ID FROM GROUP_PAGE
+                WHERE GROUP_ID IN ($placeholders)";
+                $result_group_page_query = $db->execute($sql_group_page_query,
+                $chunk);
+                while ($row = $db->fetchArray($result_group_page_query)) {
+                    $page_id_list[] = $row['ID'];
+                }
+            }
+        }
+        $current_timestamp = time();
+        $one_year_ago_timestamp = $current_timestamp - (365 * 24 * 60 * 60);
+        foreach ($unique_user_id_list as $user_id) {
+            foreach ($page_id_list as $page_id) {
+                $random_timestamp = rand($one_year_ago_timestamp,
+                $current_timestamp - 60);
+                $this->addWithDb($user_id, $page_id, C\WIKI_IMPRESSION,
+                $db, $random_timestamp);
+                L\crawlLog("Adding to DB with USER_ID: $user_id,
+                PAGE_ID: $page_id, TIMESTAMP: $random_timestamp");
+            }
+        }
+    }
+}
+
+$experiment = new ManyUserExperiment();
+$experiment->addTestData();
-- 
2.46.0.windows.1

