├── .env.dist ├── .htaccess ├── FoodScanAppService.php ├── README.md ├── cache └── .gitkeep ├── composer.json ├── composer.lock ├── config.php ├── logs └── .gitkeep └── src ├── AllowCors.php ├── ApiCrypter.php ├── ConstantValues.php ├── Database.php ├── Email.php ├── HelperFunctions.php ├── Logger.php ├── PdoFunctions.php ├── Product.php ├── Security.php ├── TableVars.php ├── ThirdParty ├── ApiProviders.php └── ScanningMethod.php └── User.php /.env.dist: -------------------------------------------------------------------------------- 1 | ## Database credentials 2 | DB_HOST="localhost" 3 | DB_USER="" 4 | DB_PWD="" 5 | DB_NAME="" 6 | 7 | 8 | ## Dev modes 9 | DEBUG_MODE=false 10 | CACHE=true 11 | 12 | 13 | ## Encryption key 14 | ENCRYPTION_KEY_IV="" 15 | 16 | 17 | ## SMTP credentials for sending emails 18 | SENDER_EMAIL_NAME="Lifyzer App" 19 | SENDER_EMAIL_ID="hello@lifyzer.com" 20 | SENDER_EMAIL_PASSWORD="" 21 | 22 | 23 | #### Food Data API Keys ### 24 | SWISS_FOOD_KEY="" 25 | USA_FOOD_KEY="" 26 | 27 | ## Food API URLs (please don't change) 28 | URL_OPEN_FOOD_NAME_API="https://ssl-api.openfoodfacts.org/cgi/search.pl?search_simple=1&json=1&action=process&fields=product_name,ingredients_text,codes_tags,image_url,nutriments,code&search_terms=" 29 | URL_OPEN_FOOD_BARCODE_API="https://world.openfoodfacts.org/api/v0/product/" 30 | URL_USA_FOOD_API="https://api.nal.usda.gov/fdc/v1/foods/search?api_key=" 31 | URL_SWISS_FOOD_API="https://www.foodrepo.org/api/v3/products/_search" 32 | -------------------------------------------------------------------------------- /.htaccess: -------------------------------------------------------------------------------- 1 | # Deny access to all CGI, Perl, Python, Bash, SQL, Template, INI configuration, .env, cache, log, temporary and text files 2 | 3 | # Apache 2.4+ 4 | 5 | Require all denied 6 | 7 | 8 | # Apache 2.2 9 | 10 | Deny from all 11 | 12 | 13 | 14 | # Deny access to all composer.json and error_log files 15 | 16 | # Apache 2.4+ 17 | 18 | Require all denied 19 | 20 | 21 | # Apache 2.2 22 | 23 | Deny from all 24 | 25 | 26 | -------------------------------------------------------------------------------- /FoodScanAppService.php: -------------------------------------------------------------------------------- 1 | pushHandler(new JsonResponseHandler); 14 | $whoops->register(); 15 | 16 | require 'config.php'; 17 | require 'src/TableVars.php'; 18 | require 'src/ConstantValues.php'; 19 | require 'src/HelperFunctions.php'; 20 | require 'src/PdoFunctions.php'; 21 | 22 | $postBody = file_get_contents('php://input'); 23 | $postBody = iconv('UTF-8', 'UTF-8//IGNORE', utf8_encode($postBody)); 24 | $postData = json_decode($postBody); 25 | 26 | $logger = new Logger(); 27 | if (DEBUG_MODE) { 28 | $logger->showErrors(); 29 | } else { 30 | $logger->hideErrors(); 31 | } 32 | unset($logger); 33 | 34 | if (!empty($_REQUEST['Service'])) { 35 | try { 36 | $db = new Database(); 37 | } catch (PDOException $except) { 38 | if (DEBUG_MODE) { 39 | echo $except->getMessage(); 40 | } else { 41 | exit('An unexpected database error occured.'); 42 | } 43 | } 44 | switch ($_REQUEST['Service']) { 45 | /*** User ***/ 46 | case User::REGISTRATION_ACTION: 47 | case User::LOGIN_ACTION: 48 | case User::CHANGE_PASSWORD_ACTION: 49 | case User::EDIT_PROFILE_ACTION: 50 | case User::FORGOT_PASSWORD_ACTION: 51 | case User::DELETE_ACCOUNT_ACTION: 52 | case User::DATA_TAKEOUT: 53 | case User::LOGS_ACTION: 54 | $access_key = validateObject($postData, 'access_key', ''); 55 | $access_key = addslashes($access_key); 56 | 57 | $secret_key = validateObject($postData, 'secret_key', ''); 58 | $secret_key = addslashes($secret_key); 59 | 60 | $isSecure = (new Security($db))->checkForSecurityNew($access_key, $secret_key); 61 | $isSecure = YES; 62 | if ($isSecure === NO) { 63 | $data['status'] = FAILED; 64 | $data['message'] = MALICIOUS_SOURCE; 65 | } elseif ($isSecure === ERROR) { 66 | $data['status'] = FAILED; 67 | $data['message'] = TOKEN_ERROR; 68 | } else { 69 | $user = new User($db); 70 | $data = $user->callService($_REQUEST['Service'], $postData); 71 | if ($isSecure !== YES || $isSecure !== YES) { 72 | if ($isSecure['key'] == 'Temp') { 73 | $data['TempToken'] = $isSecure['value']; 74 | } else { 75 | $data['UserToken'] = $isSecure['value']; 76 | } 77 | } 78 | } 79 | break; 80 | 81 | /*** Food Items & Reviews/Rating ***/ 82 | case 'addToFavourite': 83 | case 'getAllUserFavourite': 84 | case 'getProductDetails': 85 | case 'getUserHistory': 86 | case 'removeProductFromHistory': 87 | case 'addReview': 88 | case 'updateReview': 89 | case 'deleteReview': 90 | case 'getReviewList': 91 | case 'updateRatingStatus': 92 | case 'getProductDetailsV2': 93 | $access_key = validateObject($postData, 'access_key', ''); 94 | $access_key = addslashes($access_key); 95 | 96 | $secret_key = validateObject($postData, 'secret_key', ''); 97 | $secret_key = addslashes($secret_key); 98 | 99 | $isSecure = (new Security($db))->checkForSecurityNew($access_key, $secret_key); 100 | $isSecure = YES; 101 | 102 | if ($isSecure === NO) { 103 | $data['status'] = FAILED; 104 | $data['message'] = MALICIOUS_SOURCE; 105 | } elseif ($isSecure === ERROR) { 106 | $data['status'] = FAILED; 107 | $data['message'] = TOKEN_ERROR; 108 | } else { 109 | $product = new Product($db); 110 | $data = $product->callService($_REQUEST['Service'], $postData); 111 | if ($isSecure !== YES || $isSecure !== YES) { 112 | if ($isSecure['key'] === 'Temp') { 113 | $data['TempToken'] = $isSecure['value']; 114 | } else { 115 | $data['UserToken'] = $isSecure['value']; 116 | } 117 | } 118 | } 119 | break; 120 | 121 | /*** Security ***/ 122 | case Security::UPDATE_USER_TOKEN: 123 | case Security::TEST_ENCRYPTION: 124 | case Security::REFRESH_TOKEN: 125 | $security = new Security($db); 126 | $data = $security->callService($_REQUEST['Service'], $postData); 127 | break; 128 | default: 129 | $data['data'] = 'No Service Found'; 130 | $data['message'] = $_REQUEST['Service']; 131 | } 132 | } 133 | 134 | // (new AllowCors)->init(); // Set CORS headers 135 | header('Content-type: application/json'); 136 | echo json_encode($data); 137 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Food Scanner API, Backend 2 | 3 | 🍳 The YUMMIEST™ REST API for the Lifyzer Solution™ food scanner apps 😋 Thanks to the power of data 🤖, it will return back to its client apps the right result we expect 🥥 4 | 5 | ## Server Requirements 6 | 7 | * 🐘 [PHP 7.4](https://www.php.net/releases/7_4_0.php) or higher 8 | * 💾 MySQL/MariaDB 5.5.3 or higher 9 | * 🎹 [Composer](https://getcomposer.org) 10 | 11 | 12 | ## Setup 13 | 14 | 1. Run `composer install` to install the project's dependencies. 15 | 2. Create a MySQL database and import `/_development/SQL/database.sql` file. 16 | 3. ⚠️ **Don't forget** to rename `.env.dist` to `.env`. Edit the details in there such as the database, SMTP credentials, private encryption key and 3rd-party food API keys. 17 | 18 | 19 | ## Usage 20 | 21 | The index file to be called for requesting the API is `FoodScanAppService.php`. Make a request like `/FoodScanAppService.php?Service=...` to start using the food API. 22 | 23 | 24 | ## [3rd-party APIs used](https://github.com/Lifyzer/Food-Scanner-API-Backend/issues/4) 25 | 26 | * Open Food Facts 27 | * FoodData Central (FDC) - US market 28 | * The Open Food Repo 29 | 30 | 31 | ## About 32 | 33 | [Pierre-Henry Soria](https://pierrehenry.be). A super passionate software engineer. I love learning and discovering new, exciting things all the time! 🚀 34 | 35 | ☕️ Are you enjoying my work? **[Offer me a coffee](https://ko-fi.com/phenry)** and boost the software development at the same time! 💪 36 | 37 | [![@phenrysay][twitter-image]](https://twitter.com/phenrysay "Follow Me on Twitter") [![pH-7][github-image]](https://github.com/pH-7 "Follow me GitHub @pH-7") 38 | 39 | 40 | 41 | [twitter-image]: https://img.shields.io/badge/Twitter-1DA1F2?style=for-the-badge&logo=twitter&logoColor=white 42 | [github-image]: https://img.shields.io/badge/GitHub-100000?style=for-the-badge&logo=github&logoColor=white 43 | -------------------------------------------------------------------------------- /cache/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lifyzer/Food-Scanner-API-Backend/09614bd1d4951c345fee52fdfa114de1b5c62278/cache/.gitkeep -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "lifyzer/api", 3 | "description": "Lifyzer REST API for its Android/iOS apps", 4 | "type": "project", 5 | "authors": [ 6 | { 7 | "name": "Pierre-Henry Soria", 8 | "email": "hi@ph7.me", 9 | "homepage": "https://ph7.me" 10 | } 11 | ], 12 | "require": { 13 | "php": ">=7.4.0", 14 | "ext-json": "*", 15 | "vlucas/phpdotenv": "^5.4", 16 | "phpmailer/phpmailer": "^6.1", 17 | "phpfastcache/phpfastcache": "^8.0", 18 | "filp/whoops": "^2.14" 19 | }, 20 | "autoload": { 21 | "psr-4": { 22 | "Lifyzer\\Api\\": "src" 23 | } 24 | }, 25 | "require-dev": { 26 | "phpunit/phpunit": "^9.5" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /config.php: -------------------------------------------------------------------------------- 1 | dirname(__DIR__) . '/cache' 33 | ] 34 | ) 35 | ); 36 | 37 | $env = Dotenv::createImmutable(__DIR__); 38 | $env->load(); 39 | $env->required($requiredEnvFields)->notEmpty(); 40 | 41 | // First, convert "true/false" string from phpdotenv to boolean 42 | $debugMode = filter_var($_ENV['DEBUG_MODE'], FILTER_VALIDATE_BOOLEAN); 43 | $cacheStatus = filter_var($_ENV['CACHE'], FILTER_VALIDATE_BOOLEAN); 44 | define('DEBUG_MODE', $debugMode); 45 | define('CACHE_ENABLED', $cacheStatus); 46 | 47 | date_default_timezone_set('UTC'); 48 | -------------------------------------------------------------------------------- /logs/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Lifyzer/Food-Scanner-API-Backend/09614bd1d4951c345fee52fdfa114de1b5c62278/logs/.gitkeep -------------------------------------------------------------------------------- /src/AllowCors.php: -------------------------------------------------------------------------------- 1 | 4 | * @copyright (c) 2018, Pierre-Henry Soria. All Rights Reserved. 5 | * @link http://pierrehenry.be 6 | */ 7 | 8 | namespace Lifyzer\Api; 9 | 10 | class AllowCors 11 | { 12 | private const ALLOW_CORS_ORIGIN_KEY = 'Access-Control-Allow-Origin'; 13 | private const ALLOW_CORS_METHOD_KEY = 'Access-Control-Allow-Methods'; 14 | private const ALLOW_CORS_ORIGIN_VALUE = '*'; 15 | private const ALLOW_CORS_METHOD_VALUE = 'GET, POST, PUT, DELETE, PATCH, OPTIONS'; 16 | 17 | /** 18 | * Initialize the Cross-Origin Resource Sharing (CORS) headers. 19 | * 20 | * @link https://en.wikipedia.org/wiki/Cross-origin_resource_sharing More info concerning CORS headers. 21 | */ 22 | public function init(): void 23 | { 24 | $this->set(self::ALLOW_CORS_ORIGIN_KEY, self::ALLOW_CORS_ORIGIN_VALUE); 25 | $this->set(self::ALLOW_CORS_METHOD_KEY, self::ALLOW_CORS_METHOD_VALUE); 26 | } 27 | 28 | /** 29 | * Set data key to value. 30 | * 31 | * @param string $sKey The data key. 32 | * @param string $sValue The data value. 33 | */ 34 | private function set(string $sKey, string $sValue): void 35 | { 36 | header($sKey . ':' . $sValue); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/ApiCrypter.php: -------------------------------------------------------------------------------- 1 | will change to '1' when testing mode is there 17 | define('NO_ERROR', 'No error'); 18 | define('UPDATE_SUCCESS', 'update Success'); 19 | define('USERTOKEN', 'UserToken'); 20 | 21 | // ************ Messages ****************// 22 | define('SOMETHING_WENT_WRONG_TRY_AGAIN_LATER', 'We got an internal issue with our backend. Please try again later'); 23 | define('EMAIL_ALREADY_EXISTS', 'Email ID already exists'); 24 | define('REGISTRATION_SUCCESSFULLY_DONE', 'Registration successfully done'); 25 | define('MALICIOUS_SOURCE', 'Another session for this user has been detected in another device. Please logout and verify your number again to continue using the app.'); 26 | define('TOKEN_ERROR', 'Please ensure that security token is supplied in your request'); 27 | define('DEFAULT_NO_RECORD', 'No record found'); 28 | define('WRONG_PASSWORD_MESSAGE', 'You have entered a wrong password'); 29 | define('CHNG_WRONG_PASSWORD_MESSAGE', 'Old password is incorrect'); 30 | define('NO_DATA_AVAILABLE', 'No data available'); 31 | define('NO_EMAIL_AND_PASSWORD_AVAILABLE', 'Email ID or Password is incorrect.'); 32 | define('USER_LOGIN_SUCCESSFULLY', 'User Login Successfully'); 33 | define('PASSWORD_CHANGED', 'Password successfully changed!'); 34 | define('PASSWORD_SENT', 'Password is sent successfully'); 35 | define('NO_FAVOURITE_PRODUCT_FOUND', 'No Favourite Product not found'); 36 | define('NO_FAVOURITE_HISTORY_FOUND', 'No History not found'); 37 | define('NO_PRODUCT_FOUND_IN_DATABASE', 'No Product found in database'); 38 | define('NO_PRODUCT_AVAILABLE', 'No Product Available'); 39 | define('PRODUCT_FETCHED_SUCCESSFULLY', 'Product successfully fetched'); 40 | define('DATA_FETCHED_SUCCESSFULLY', 'Data fetched successfully'); 41 | define('HISTORY_REMOVED_SUCCESSFULLY', 'History deleted successfully'); 42 | define('FAVOURITE_SUCCESSFULLY', 'Added to favourite Successfully'); 43 | define('REMOVE_FAVOURITE_SUCCESSFULLY', 'Product removed from favourite.'); 44 | define('PROFILE_UPDATED_SUCCESSFULLY', 'Profile Updated Successfully'); 45 | define('NO_REVIEW_FOUND', 'No Review found'); 46 | define('REVIEW_REMOVED_SUCCESSFULLY', 'Review deleted successfully'); 47 | define('REVIEW_ADDED_SUCCESSFULLY', 'Review added successfully'); 48 | define('REVIEW_UPDATED_SUCCESSFULLY', 'Review updated successfully'); 49 | define('RATING_STATUS_STORED_SUCCESSFULLY', 'Rating status updated successfully'); 50 | 51 | abstract class DELETE_STATUS 52 | { 53 | const IS_DELETE = '1'; 54 | const NOT_DELETE = '0'; 55 | } 56 | -------------------------------------------------------------------------------- /src/Database.php: -------------------------------------------------------------------------------- 1 | 4 | * @copyright (c) 2018, Pierre-Henry Soria. All Rights Reserved. 5 | * @license GNU General Public License; 6 | */ 7 | 8 | declare(strict_types=1); 9 | 10 | namespace Lifyzer\Api; 11 | 12 | use PDO; 13 | 14 | class Database extends PDO 15 | { 16 | private const DSN_MYSQL_PREFIX = 'mysql'; 17 | private const DSN_POSTGRESQL_PREFIX = 'pgsql'; 18 | private const DBMS_CHARSET = 'UTF8MB4'; 19 | 20 | public function __construct() 21 | { 22 | $details = $this->getDetails(); 23 | $driverOptions[PDO::MYSQL_ATTR_INIT_COMMAND] = "SET NAMES {$details['charset']}"; 24 | parent::__construct( 25 | "{$details['db_type']}:host={$details['host']};dbname={$details['name']};", 26 | $details['user'], 27 | $details['password'], 28 | $driverOptions 29 | ); 30 | $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 31 | } 32 | 33 | private function getDetails(): array 34 | { 35 | return [ 36 | 'db_type' => self::DSN_MYSQL_PREFIX, 37 | 'host' => $_ENV['DB_HOST'], 38 | 'name' => $_ENV['DB_NAME'], 39 | 'user' => $_ENV['DB_USER'], 40 | 'password' => $_ENV['DB_PWD'], 41 | 'charset' => self::DBMS_CHARSET 42 | ]; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Email.php: -------------------------------------------------------------------------------- 1 | oMail = new PHPMailer(); 21 | } 22 | 23 | /** 24 | * @param string $message 25 | * @param string $subject 26 | * @param string $userEmailId 27 | * 28 | * @return bool 29 | * 30 | * @throws Exception 31 | */ 32 | public function sendMail(string $message, string $subject, string $userEmailId): bool 33 | { 34 | $sName = $_ENV['SENDER_EMAIL_NAME']; 35 | $senderEmailId = $_ENV['SENDER_EMAIL_ID']; 36 | $senderEmailPassword = $_ENV['SENDER_EMAIL_PASSWORD']; 37 | 38 | // Server settings 39 | $this->oMail->isSMTP(); 40 | $this->oMail->CharSet = PHPMailer::CHARSET_UTF8; 41 | $this->oMail->SMTPSecure = self::SMTP_PREFIX_SERVER; 42 | $this->oMail->SMTPAuth = true; 43 | $this->oMail->Port = self::SMTP_PORT_SERVER; 44 | $this->oMail->Host = self::SMTP_HOST_SERVER; 45 | $this->oMail->Username = $senderEmailId; 46 | $this->oMail->Password = $senderEmailPassword; 47 | $this->oMail->SMTPDebug = SMTP::DEBUG_SERVER; // When need to show log of SMTP process 48 | 49 | // Recipients 50 | $this->oMail->setFrom($senderEmailId, $sName); 51 | $this->oMail->addAddress($userEmailId); 52 | 53 | // Content 54 | $this->oMail->isHTML(true); 55 | $this->oMail->Subject = $subject; 56 | $this->oMail->Body = $message; 57 | 58 | return (bool)$this->oMail->send(); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/HelperFunctions.php: -------------------------------------------------------------------------------- 1 | 0 ? $value : $placeHolder; 27 | return $value; 28 | } 29 | 30 | function validateObject($object, $key, $placeHolder) 31 | { 32 | if (isset($object->$key)) { 33 | return $object->$key; 34 | } 35 | 36 | return $placeHolder; 37 | } 38 | 39 | function getDefaultDate(): string 40 | { 41 | return date(DATETIME_FORMAT); 42 | } 43 | 44 | function encryptPassword(string $password): string 45 | { 46 | return sha1($password); 47 | } 48 | 49 | function generateRandomString(int $length = 10): string 50 | { 51 | $randomString = ''; 52 | for ($i = 0; $i < $length; $i++) { 53 | $randomString .= BASE62_CHARACTERS[rand(0, strlen(BASE62_CHARACTERS) - 1)]; 54 | } 55 | 56 | return $randomString; 57 | } 58 | 59 | function curlRequestLoad($url, $isParam = false, $params = '') 60 | { 61 | $ch = curl_init(); 62 | curl_setopt_array( 63 | $ch, 64 | [ 65 | CURLOPT_URL => $url, 66 | CURLOPT_RETURNTRANSFER => true, 67 | CURLOPT_SSL_VERIFYPEER => false, 68 | CURLOPT_SSL_VERIFYHOST => 0, 69 | ] 70 | ); 71 | 72 | if ($isParam) { 73 | curl_setopt_array(CURLOPT_POSTFIELDS, $params); 74 | } 75 | 76 | $result = curl_exec($ch); 77 | curl_close($ch); 78 | 79 | return json_decode($result, true); 80 | } 81 | -------------------------------------------------------------------------------- /src/Logger.php: -------------------------------------------------------------------------------- 1 | '; 40 | echo $identifer; 41 | echo "
"; 42 | print_r($content); 43 | echo "
"; 44 | echo '
';
45 |     }
46 | 
47 |     public function writeToFile($identifer, $content, $filename): void
48 |     {
49 |         $logtime = date('m/d/Y h:i:s a', time());
50 |         // The new person to add to the file
51 |         $person = $logtime . "\n\n $identifer" . serialize($content);// Write the contents to the file,
52 |         // using the FILE_APPEND flag to append the content to the end of the file
53 |         // and the LOCK_EX flag to prevent anyone else writing to the file at the same time
54 |         file_put_contents($filename, $person, FILE_APPEND | LOCK_EX);
55 |     }
56 | }
57 | 


--------------------------------------------------------------------------------
/src/PdoFunctions.php:
--------------------------------------------------------------------------------
  1 |  $value) {
 21 |             if (++$cnt == $numItems) {
 22 |                 $fields .= $key;
 23 |                 $values .= ':' . $key;
 24 |             } else {
 25 |                 $fields .= $key . ',';
 26 |                 $values .= ':' . $key . ' , ';
 27 |             }
 28 |         }
 29 |         $sql = 'INSERT INTO ' . $tableName . ' (' . $fields . ' ) VALUES (' . $values . ') ';
 30 |         if ($stmt = $connection->prepare($sql)) {
 31 |             foreach ($dataArray as $key => $value) {
 32 |                 $stmt->bindValue(":$key", $value, PDO::PARAM_STR);
 33 |             }
 34 |             if ($stmt->execute()) {
 35 |                 $status = SUCCESS;
 36 |                 $message = $connection->lastInsertId();
 37 |                 $stmt->closeCursor();
 38 |             }
 39 |         }
 40 |     } catch (PDOException $exception) {
 41 |         $message = $exception->getMessage();
 42 |         $err_msg = "\nFunction=> " . $functionName . " Query=> " . $sql . "  Error message= " . $message;
 43 |         errorLogFunction($err_msg);
 44 |         if (is_array($message)) {
 45 |             $message = implode(" , ", $message);
 46 |         }
 47 |     }
 48 |     $data['status'] = $status;
 49 |     $data['message'] = $message;
 50 |     $data['sql'] = $sql;
 51 |     return $data;
 52 | }
 53 | 
 54 | function editData(PDO $connection, $functionName, $tableName, $dataArray, $conditionArray, $query = '')
 55 | {
 56 |     $sql = '';
 57 |     $data = [];
 58 |     try {
 59 |         $numOfItems = count($dataArray);
 60 |         $numOfItemsForCondition = count($conditionArray);
 61 |         $cnt = 0;
 62 |         $cntForCondition = 0;
 63 |         $values = "";
 64 |         $conditionValue = "";
 65 |         $execute_arr = [];
 66 |         foreach ($dataArray as $key => $value) {
 67 |             if (empty($query)) {
 68 |                 if (++$cnt == $numOfItems) {
 69 |                     $values .= $key . " = :$key ";
 70 |                 } else {
 71 |                     $values .= $key . " = :$key , ";
 72 |                 }
 73 |             }
 74 |             $execute_arr[":$key"] = $value;
 75 |         }
 76 |         foreach ($conditionArray as $key => $value) {
 77 |             if (++$cntForCondition == $numOfItemsForCondition) {
 78 |                 $conditionValue .= $key . " = :$key ";
 79 |             } else {
 80 |                 $conditionValue .= $key . " = :$key AND ";
 81 |             }
 82 |             $execute_arr[":$key"] = $value;
 83 |         }
 84 |         if (empty($query)) {
 85 |             $sql = 'UPDATE ' . $tableName . ' SET ' . $values . ' WHERE ' . $conditionValue;
 86 |         } else {
 87 |             $sql = $query;
 88 |         }
 89 |         $stmt = $connection->prepare($sql);
 90 |         foreach ($dataArray as $key => $value) {
 91 |             $stmt->bindValue(":$key", $value);
 92 |         }
 93 |         foreach ($conditionArray as $key => $value) {
 94 |             $stmt->bindValue(":$key", $value);
 95 |         }
 96 |         $stmt->execute();
 97 |         $status = SUCCESS;
 98 |         $message = UPDATE_SUCCESS;
 99 |         $stmt->closeCursor();
100 |     } catch (PDOException $exception) {
101 |         $status = FAILED;
102 |         $message = $exception->getMessage();
103 |         $err_msg = "\nFunction=> " . $functionName . " Query=> " . $sql . "  Error message= " . $message;
104 |         errorLogFunction($err_msg);
105 |     }
106 |     $data['status'] = $status;
107 |     $data['message'] = $message;
108 |     $data['sql'] = $sql;
109 |     return $data;
110 | }
111 | 
112 | function getSingleTableData(PDO $connection, $table, $sql, $columns, $customCondition, $dataArray)
113 | {
114 |     try {
115 |         $numOfItems = count($dataArray);
116 |         $cnt = 0;
117 |         $execute_array = [];
118 |         $condition = '';
119 |         if (!empty($dataArray)) {
120 |             foreach ($dataArray as $key => $value) {
121 |                 if (empty($sql)) {
122 |                     if (empty($customCondition)) {
123 |                         if (++$cnt == $numOfItems) {
124 |                             $condition .= $key . " = :$key ";
125 |                         } else {
126 |                             $condition .= $key . " = :$key AND ";
127 |                         }
128 |                     }
129 |                 }
130 |                 $execute_array[":$key"] = $value;
131 |             }
132 |         }
133 |         $check_conditions = $customCondition;
134 |         if (empty($customCondition)) {
135 |             $check_conditions = $condition;
136 |         }
137 |         if (empty($sql)) {
138 |             $sql = 'SELECT ' . $columns . ' FROM ' . $table . ' WHERE ' . $check_conditions;
139 |         }
140 |         $statement = $connection->prepare($sql);
141 |         if (!empty($dataArray)) {
142 |             foreach ($dataArray as $key => $value) {
143 |                 $statement->bindValue(":$key", $value);
144 |             }
145 |         }
146 |         $statement->execute();
147 |         $result = $statement->fetch(PDO::FETCH_ASSOC);
148 |         $statement->closeCursor();
149 |     } catch (PDOException $e) {
150 |         $message = $e->getMessage();
151 |         $result['message'] = $message;
152 |         $err_msg = "\nFunction=> " . " Query=> " . $sql . "  Error message= " . $message;
153 |         errorLogFunction($err_msg);
154 |     }
155 |     return $result;
156 | }
157 | 
158 | function getSingleTableDataLastDate(PDO $connection, $table, $sql, $columns, $customCondition, $dataArray)
159 | {
160 |     try {
161 |         $numOfItems = count($dataArray);
162 |         $cnt = 0;
163 |         $execute_array = [];
164 |         $condition = '';
165 |         if (!empty($dataArray)) {
166 |             foreach ($dataArray as $key => $value) {
167 |                 if (empty($sql)) {
168 |                     if (empty($customCondition)) {
169 |                         if (++$cnt == $numOfItems) {
170 |                             $condition .= $key . " = :$key ";
171 |                         } else {
172 |                             $condition .= $key . " = :$key AND ";
173 |                         }
174 |                     }
175 |                 }
176 |                 $execute_array[":$key"] = $value;
177 |             }
178 |         }
179 |         if (empty($customCondition)) {
180 |             $check_conditions = $condition;
181 |         } else {
182 |             $check_conditions = $customCondition;
183 |         }
184 |         if (empty($sql)) {
185 |             $sql = 'SELECT ' . $columns . ' FROM ' . $table . ' WHERE ' . $check_conditions;
186 |         }
187 |         $sql = $sql . ' ORDER BY modified_date DESC';
188 |         $statement = $connection->prepare($sql);
189 |         if (!empty($dataArray)) {
190 |             foreach ($dataArray as $key => $value) {
191 |                 $statement->bindValue(":$key", $value);
192 |             }
193 |         }
194 |         $statement->execute();
195 |         $result = $statement->fetch(PDO::FETCH_ASSOC);
196 |         $statement->closeCursor();
197 |     } catch (PDOException $e) {
198 |         $message = $e->getMessage();
199 |         $result['message'] = $message;
200 |         $err_msg = "\nFunction=> " . " Query=> " . $sql . "  Error message= " . $message;
201 |         errorLogFunction($err_msg);
202 |     }
203 |     return $result;
204 | }
205 | 
206 | function getMultipleTableData(PDO $connection, $table, $sql, $columns, $customCondition, array $dataArray = null)
207 | {
208 |     try {
209 |         $numOfItems = count($dataArray);
210 |         $cnt = 0;
211 |         $execute_array = [];
212 |         $condition = '';
213 |         if (!empty($dataArray)) {
214 |             foreach ($dataArray as $key => $value) {
215 |                 if (empty($sql)) {
216 |                     if (empty($customCondition)) {
217 |                         if (++$cnt == $numOfItems) {
218 |                             $condition .= $key . " = :$key ";
219 |                         } else {
220 |                             $condition .= $key . " = :$key AND ";
221 |                         }
222 |                     }
223 |                 }
224 |                 $execute_array[":$key"] = $value;
225 |             }
226 |         }
227 |         if (empty($customCondition)) {
228 |             $check_conditions = $condition;
229 |         } else {
230 |             $check_conditions = $customCondition;
231 |         }
232 |         if (empty($sql)) {
233 |             if (empty($sql)) {
234 |                 $sql = 'SELECT ' . $columns . ' FROM ' . $table . ' WHERE ' . $check_conditions;
235 |             }
236 |         }
237 |         $statement = $connection->prepare($sql);
238 |         if (!empty($dataArray)) {
239 |             foreach ($dataArray as $key => $value) {
240 |                 $statement->bindValue(":$key", $value);
241 |             }
242 |         }
243 |         $statement->execute();
244 |     } catch (PDOException $e) {
245 |         $err_msg = "\nFunction=> " . " Query=> " . $sql . "  Error message= " . $e->getMessage();
246 |         errorLogFunction($err_msg);
247 |         $message = $e->getMessage();
248 |         if (is_array($message)) {
249 |             $error_message = implode(" , ", $message);
250 |         } else {
251 |             $error_message = $message;
252 |         }
253 |         return $error_message;
254 |     }
255 |     return $statement;
256 | }
257 | 


--------------------------------------------------------------------------------
/src/Product.php:
--------------------------------------------------------------------------------
   1 | connection = $con;
  18 |     }
  19 | 
  20 |     public function callService($service, $postData): ?array
  21 |     {
  22 |         switch ($service) {
  23 |             case 'updateRatingStatus':
  24 |                 return $this->updateRatingStatus($postData);
  25 | 
  26 |             case 'addToFavourite':
  27 |                 return $this->addToFavourite($postData);
  28 | 
  29 |             case 'getAllUserFavourite':
  30 |                 return $this->getAllUserFavourite($postData);
  31 | 
  32 |             case 'getProductDetails':
  33 |                 return $this->getProductDetails($postData);
  34 | 
  35 |             case 'getProductDetailsV2':
  36 |                 return $this->getProductDetailsV2($postData);
  37 | 
  38 |             case 'getUserHistory':
  39 |                 return $this->getUserHistory($postData);
  40 | 
  41 |             case 'removeProductFromHistory':
  42 |                 return $this->removeProductFromHistory($postData);
  43 | 
  44 |             case 'addReview':
  45 |                 return $this->addReview($postData);
  46 | 
  47 |             case 'getReviewList':
  48 |                 return $this->getReviewList($postData);
  49 | 
  50 |             case 'updateReview':
  51 |                 return $this->updateReview($postData);
  52 | 
  53 |             case 'deleteReview':
  54 |                 return $this->deleteReview($postData);
  55 | 
  56 |             default:
  57 |                 return null;
  58 |         }
  59 |     }
  60 | 
  61 |     public function updateRatingStatus($userData)
  62 |     {
  63 |         $connection = $this->connection;
  64 | 
  65 |         $user_id = validateObject($userData, 'user_id', '');
  66 |         $user_id = addslashes($user_id);
  67 | 
  68 |         $device_type = validateObject($userData, 'device_type', '');
  69 |         $device_type = addslashes($device_type);
  70 | 
  71 |         $rate_status = '1';
  72 | 
  73 |         $select_user_rated_query = "SELECT * from " . TABLE_RATING . " WHERE user_id = " . $user_id . " 
  74 |                                     AND is_rate = '1'
  75 |                                     AND device_type = '" . $device_type . "'
  76 |                                     AND is_test = '" . IS_TESTDATA . "' AND is_delete = '" . IS_DELETE . "' ";
  77 |         $select_user_rated_stmt = getSingleTableData(
  78 |             $connection,
  79 |             '',
  80 |             $select_user_rated_query,
  81 |             '',
  82 |             '',
  83 |             []
  84 |         );
  85 |         if (empty($select_user_rated_stmt)) {
  86 |             $conditional_array = [
  87 |                 'is_rate' => $rate_status,
  88 |                 'user_id' => $user_id,
  89 |                 'device_type' => $device_type,
  90 |                 'is_test' => IS_TESTDATA
  91 |             ];
  92 |             $rating_response = addData(
  93 |                 $connection,
  94 |                 "updateRatingStatus",
  95 |                 TABLE_RATING,
  96 |                 $conditional_array
  97 |             );
  98 | 
  99 |             if ($rating_response[STATUS_KEY] === SUCCESS) {
 100 |                 $message = RATING_STATUS_STORED_SUCCESSFULLY;
 101 |                 $status = SUCCESS;
 102 |             } else {
 103 |                 $status = FAILED;
 104 |                 $message = SOMETHING_WENT_WRONG_TRY_AGAIN_LATER;
 105 |             }
 106 |         } else {
 107 |             $message = RATING_STATUS_STORED_SUCCESSFULLY;
 108 |             $status = SUCCESS;
 109 |         }
 110 |         $data['status'] = $status;
 111 |         $data['message'] = $message;
 112 | 
 113 |         return $data;
 114 |     }
 115 | 
 116 |     public function deleteReview($userData)
 117 |     {
 118 |         $connection = $this->connection;
 119 | 
 120 |         $review_id = validateObject($userData, 'review_id', '');
 121 |         $review_id = addslashes($review_id);
 122 | 
 123 |         $edit_history_response = editData(
 124 |             $connection,
 125 |             'deleteReview',
 126 |             TABLE_REVIEW,
 127 |             ['is_delete' => DELETE_STATUS::IS_DELETE],
 128 |             ['id' => $review_id, 'is_test' => IS_TESTDATA],
 129 |             ''
 130 |         );
 131 |         if ($edit_history_response[STATUS_KEY] === SUCCESS) {
 132 |             $message = REVIEW_REMOVED_SUCCESSFULLY;
 133 |             $status = SUCCESS;
 134 |         } else {
 135 |             $status = FAILED;
 136 |             $message = SOMETHING_WENT_WRONG_TRY_AGAIN_LATER;
 137 |         }
 138 |         $data['status'] = $status;
 139 |         $data['message'] = $message;
 140 |         return $data;
 141 |     }
 142 | 
 143 |     public function updateReview($userData)
 144 |     {
 145 |         $connection = $this->connection;
 146 | 
 147 |         $user_id = validateObject($userData, 'user_id', '');
 148 |         $user_id = addslashes($user_id);
 149 | 
 150 |         $review_id = validateObject($userData, 'review_id', '');
 151 |         $review_id = addslashes($review_id);
 152 | 
 153 |         $ratting = validateObject($userData, 'ratting', '');
 154 |         $ratting = addslashes($ratting);
 155 | 
 156 |         $desc = validateObject($userData, 'desc', '');
 157 |         $desc = utf8_decode($desc);
 158 | 
 159 |         $is_rate = false;
 160 | 
 161 |         $edit_review_response = editData(
 162 |             $connection,
 163 |             'updateReview',
 164 |             TABLE_REVIEW,
 165 |             ['ratting' => $ratting, 'description' => $desc],
 166 |             ['id' => $review_id, 'is_test' => IS_TESTDATA, 'is_delete' => IS_DELETE],
 167 |             ''
 168 |         );
 169 | 
 170 |         if ($edit_review_response[STATUS_KEY] === SUCCESS) {
 171 |             $message = REVIEW_UPDATED_SUCCESSFULLY;
 172 |             $status = SUCCESS;
 173 |             //START : if user have left 2 comments or rated 3 products (or more) then will rate status as TRUE else FALSE.
 174 |             $rate_status = $this->isUserRate($user_id);
 175 |             if ($rate_status === SUCCESS) {
 176 |                 $select_user_rate_query = "(SELECT COUNT(*) from " . TABLE_REVIEW . " WHERE user_id = " . $user_id . " AND is_test = '" . IS_TESTDATA . "' AND is_delete = '" . IS_DELETE . "') as count_rate";
 177 |                 $select_user_desc_query = "(SELECT COUNT(*) from " . TABLE_REVIEW . " WHERE user_id = " . $user_id . " AND is_test = '" . IS_TESTDATA . "' AND is_delete = '" . IS_DELETE . "' AND description != '') as count_comment";
 178 |                 $select_user_review_query = "SELECT " . $select_user_rate_query . "," . $select_user_desc_query;
 179 |                 $select_user_review_stmt = getSingleTableData(
 180 |                     $connection,
 181 |                     '',
 182 |                     $select_user_review_query,
 183 |                     '',
 184 |                     '',
 185 |                     []
 186 |                 );
 187 |                 if (!empty($select_user_review_stmt) &&
 188 |                     ($select_user_review_stmt['count_comment'] >= 2 || $select_user_review_stmt["count_rate"] >= 3)) {
 189 |                     $is_rate = true;
 190 |                 } else {
 191 |                     $is_rate = false;
 192 |                 }
 193 |             } else {
 194 |                 $is_rate = false;
 195 |             }
 196 |             //END
 197 |         } else {
 198 |             $status = FAILED;
 199 |             $message = SOMETHING_WENT_WRONG_TRY_AGAIN_LATER;
 200 |         }
 201 |         $data['is_rate'] = $is_rate;
 202 |         $data['status'] = $status;
 203 |         $data['message'] = $message;
 204 |         return $data;
 205 |     }
 206 | 
 207 |     public function addReview($userData)
 208 |     {
 209 |         $connection = $this->connection;
 210 | 
 211 |         $user_id = validateObject($userData, 'user_id', '');
 212 |         $user_id = addslashes($user_id);
 213 | 
 214 |         $product_id = validateObject($userData, 'product_id', '');
 215 |         $product_id = addslashes($product_id);
 216 | 
 217 |         $ratting = validateObject($userData, 'ratting', '');
 218 |         $ratting = addslashes($ratting);
 219 | 
 220 |         $desc = validateObject($userData, 'desc', '');
 221 |         $desc = utf8_decode($desc);
 222 | 
 223 |         $is_rate = false;
 224 | 
 225 |         editData(
 226 |             $connection,
 227 |             'updateReview',
 228 |             TABLE_REVIEW,
 229 |             ['is_delete' => DELETE_STATUS::IS_DELETE],
 230 |             ['user_id' => $user_id, 'product_id' => $product_id, 'is_test' => IS_TESTDATA, 'is_delete' => IS_DELETE],
 231 |             ''
 232 |         );
 233 | 
 234 |         $conditional_array = [
 235 |             'user_id' => $user_id,
 236 |             'product_id' => $product_id,
 237 |             'ratting' => $ratting,
 238 |             'description' => $desc,
 239 |             'is_test' => IS_TESTDATA
 240 |         ];
 241 |         $favourite_response = addData(
 242 |             $connection,
 243 |             'addReview',
 244 |             TABLE_REVIEW,
 245 |             $conditional_array
 246 |         );
 247 | 
 248 |         if ($favourite_response[STATUS_KEY] === SUCCESS) {
 249 |             $status = SUCCESS;
 250 |             $message = REVIEW_ADDED_SUCCESSFULLY;
 251 |             //START : if user have left 2 comments or rated 3 products (or more) then will rate status as TRUE else FALSE.
 252 |             $rate_status = $this->isUserRate($user_id);
 253 |             if ($rate_status === SUCCESS) {
 254 |                 $select_user_rate_query = "(SELECT COUNT(*) from " . TABLE_REVIEW . " WHERE user_id = " . $user_id . " AND is_test = '" . IS_TESTDATA . "' AND is_delete = '" . IS_DELETE . "') as count_rate";
 255 |                 $select_user_desc_query = "(SELECT COUNT(*) from " . TABLE_REVIEW . " WHERE user_id = " . $user_id . " AND is_test = '" . IS_TESTDATA . "' AND is_delete = '" . IS_DELETE . "' AND description != '') as count_comment";
 256 |                 $select_user_review_query = "SELECT " . $select_user_rate_query . "," . $select_user_desc_query;
 257 |                 $select_user_review_stmt = getSingleTableData($connection, '', $select_user_review_query, '', '', []);
 258 |                 if (!empty($select_user_review_stmt) &&
 259 |                     ($select_user_review_stmt['count_comment'] >= 2 || $select_user_review_stmt["count_rate"] >= 3)) {
 260 |                     $is_rate = true;
 261 |                 } else {
 262 |                     $is_rate = false;
 263 |                 }
 264 |             } else {
 265 |                 $is_rate = false;
 266 |             }
 267 |             //END
 268 |         } else {
 269 |             $status = FAILED;
 270 |             $message = SOMETHING_WENT_WRONG_TRY_AGAIN_LATER;
 271 |         }
 272 |         $data['is_rate'] = $is_rate;
 273 |         $data['status'] = $status;
 274 |         $data['message'] = $message;
 275 |         return $data;
 276 |     }
 277 | 
 278 |     public function getReviewList($userData)
 279 |     {
 280 |         $connection = $this->connection;
 281 |         $user_id = validateObject($userData, 'user_id', '');
 282 |         $user_id = addslashes($user_id);
 283 | 
 284 |         $product_id = validateObject($userData, 'product_id', '');
 285 |         $product_id = addslashes($product_id);
 286 | 
 287 |         $to_index = validateObject($userData, 'to_index', '');
 288 |         $to_index = addslashes($to_index);
 289 | 
 290 |         $from_index = validateObject($userData, 'from_index', '');
 291 |         $from_index = addslashes($from_index);
 292 | 
 293 |         $posts = [];
 294 | 
 295 |         $select_total_review_query = "Select count(*) as total_review, avg(ratting) as avg_review , sum(ratting) as total_ratting from " . TABLE_REVIEW . " r where product_id = '" . $product_id . "' and is_test = '" . IS_TESTDATA . "' and is_delete = '" . IS_DELETE . "'";
 296 |         $select_total_review_stmt = getSingleTableData(
 297 |             $connection,
 298 |             '',
 299 |             $select_total_review_query,
 300 |             '',
 301 |             '',
 302 |             ''
 303 |         );
 304 |         if (!empty($select_total_review_stmt)) {
 305 |             $posts['total_review'] = $select_total_review_stmt['total_review'];
 306 |             $posts['avg_review'] = $select_total_review_stmt['avg_review'];
 307 |             $posts['total_ratting'] = $select_total_review_stmt['total_ratting'];
 308 |         }
 309 | 
 310 |         $select_total_cust_review_query = "Select count(*) as total_cust_review, avg(ratting) as avg_cust_review from " . TABLE_REVIEW . " r where user_id != '" . $user_id . "' and product_id = '" . $product_id . "' and is_test = '" . IS_TESTDATA . "' and is_delete = '" . IS_DELETE . "'";
 311 |         $select_total_cust_review_stmt = getSingleTableData(
 312 |             $connection,
 313 |             '',
 314 |             $select_total_cust_review_query,
 315 |             '',
 316 |             '',
 317 |             ''
 318 |         );
 319 |         if (!empty($select_total_cust_review_stmt)) {
 320 |             $posts['total_cust_review'] = $select_total_cust_review_stmt['total_cust_review'];
 321 |             $posts['avg_cust_review'] = $select_total_cust_review_stmt['avg_cust_review'];
 322 |         }
 323 | 
 324 |         $select_total_user_query = "Select count(*) as total_user from " . TABLE_USER . " u where is_test = '" . IS_TESTDATA . "' and is_delete = '" . IS_DELETE . "'";
 325 |         $select_total_user_stmt = getSingleTableData(
 326 |             $connection,
 327 |             '',
 328 |             $select_total_user_query,
 329 |             '',
 330 |             '',
 331 |             ''
 332 |         );
 333 |         if (!empty($select_total_user_stmt)) {
 334 |             $posts['total_user'] = $select_total_user_stmt['total_user'];
 335 |         }
 336 | 
 337 |         $select_user_query = "Select r.id,u.first_name,u.last_name,u.user_image,r.description,r.ratting,r.modified_date from " . TABLE_REVIEW . " r," . TABLE_USER . " u," . TABLE_PRODUCT . " p where r.is_test = '" . IS_TESTDATA . "' and  r.user_id = u.id and r.product_id = p.id and r.user_id = '" . $user_id . "' and r.product_id = '" . $product_id . "' and r.is_delete = '" . IS_DELETE . "'";
 338 |         $select_user_stmt = getMultipleTableData(
 339 |             $connection,
 340 |             '',
 341 |             $select_user_query,
 342 |             '',
 343 |             ''
 344 |         );
 345 |         if ($select_user_stmt->rowCount() > 0) {
 346 |             while ($product = $select_user_stmt->fetch(PDO::FETCH_ASSOC)) {
 347 |                 $posts['user_review'][] = $product;
 348 |             }
 349 |         } else {
 350 |             $posts['user_review'] = [];
 351 |         }
 352 | 
 353 |         $select_customer_query = "Select r.id,u.first_name,u.last_name,u.user_image,r.description,r.ratting,r.modified_date from " . TABLE_REVIEW . " r," . TABLE_USER . " u," . TABLE_PRODUCT . " p where r.is_test = '" . IS_TESTDATA . "' and  r.user_id = u.id and r.product_id = p.id and r.user_id != '" . $user_id . "' and r.product_id = '" . $product_id . "' and r.is_delete = '" . IS_DELETE . "' ORDER BY r.created_date DESC limit $from_index,$to_index ";
 354 |         $select_customer_stmt = getMultipleTableData(
 355 |             $connection,
 356 |             '',
 357 |             $select_customer_query,
 358 |             '',
 359 |             ''
 360 |         );
 361 |         if ($select_customer_stmt->rowCount() > 0) {
 362 |             while ($product = $select_customer_stmt->fetch(PDO::FETCH_ASSOC)) {
 363 |                 $posts['customer_review'][] = $product;
 364 |             }
 365 |         } else {
 366 |             $posts['customer_review'] = [];
 367 |         }
 368 | 
 369 |         $data['status'] = SUCCESS;
 370 |         $data['message'] = DATA_FETCHED_SUCCESSFULLY;
 371 |         $data['data'] = $posts;
 372 |         return $data;
 373 |     }
 374 | 
 375 |     public function startsWith($haystack, $needle)
 376 |     {
 377 |         if (substr($haystack, 0, strlen($needle)) === $needle) {
 378 |             return true;
 379 |         } else {
 380 |             return false;
 381 |         }
 382 |     }
 383 | 
 384 |     public function getOpenFoodDetails($product_name, $scan_type)
 385 |     {
 386 |         $temp = -1;
 387 |         $skip = false;
 388 |         $selected_index = -1;
 389 |         $product_array = [];
 390 |         switch ($scan_type) {
 391 |             case ScanningMethod::PRODUCT_NAME:
 392 |                 $url = $_ENV['URL_OPEN_FOOD_NAME_API'] . urlencode($product_name) . '&page=1';
 393 |                 $tempArr = curlRequestLoad($url);
 394 |                 if (count($tempArr['products']) > 0) {
 395 |                     foreach ($tempArr['products'] as $key => $value) {
 396 |                         $temp++;
 397 |                         if (!$skip && ($value["product_name"] == $product_name ||
 398 |                                 $this->startsWith($value["product_name"], $product_name))) {
 399 |                             $selected_index = $temp;
 400 |                             $skip = true;
 401 |                         }
 402 |                     }
 403 |                     if ($selected_index >= 0) {
 404 |                         $value = $tempArr['products'][$selected_index];
 405 |                     } else {
 406 |                         $value = $tempArr['products'][0];
 407 |                     }
 408 |                     $product_array = [
 409 |                         'barcode_id' => ($value['code'] ? $value['code'] : ''),
 410 |                         'product_name' => ($value['product_name'] ? $value['product_name'] : ''),
 411 |                         'ingredients' => ($value['ingredients_text'] ? $value['ingredients_text'] : ''),
 412 |                         'saturated_fats' => ($value["nutriments"]["saturated-fat"] ? $value["nutriments"]["saturated-fat"] : 0),
 413 |                         'protein' => ($value["nutriments"]["proteins"] ? $value["nutriments"]["proteins"] : 0),
 414 |                         'sugar' => ($value["nutriments"]["sugars"] ? $value["nutriments"]["sugars"] : 0),
 415 |                         'salt' => ($value["nutriments"]["salt"] ? $value["nutriments"]["salt"] : 0),
 416 |                         'carbohydrate' => ($value["nutriments"]["carbohydrates"] ? $value["nutriments"]["carbohydrates"] : 0),
 417 |                         'dietary_fiber' => ($value["nutriments"]["fiber_value"] ? $value["nutriments"]["fiber_value"] : 0),
 418 |                         'sodium' => ($value["nutriments"]["sodium"] ? $value["nutriments"]["sodium"] : 0)
 419 |                     ];
 420 |                     if (!empty($product_array)) {
 421 |                         if (array_key_exists("image_url", $value)) {
 422 |                             $product_array['product_image'] = ($value["image_url"] ? $value["image_url"] : '');//validateValue($value['image_url'], '');
 423 |                         }
 424 |                         if (array_key_exists("fat_amount", $value)) {
 425 |                             $product_array['fat_amount'] = ($value["nutriments"]["fat_amount"] ? $value["nutriments"]["fat_amount"] : '');//$value["nutriments"]["fat_amount"];
 426 |                         }
 427 |                     }
 428 |                 }
 429 |                 break;
 430 |             case ScanningMethod::BARCODE:
 431 |                 $url = $_ENV['URL_OPEN_FOOD_BARCODE_API'] . urlencode($product_name) . ".json";
 432 |                 $tempArr = curlRequestLoad($url);
 433 |                 if (count($tempArr['product']) > 0) {
 434 |                     $value = $tempArr['product'];
 435 |                     $product_array = [
 436 |                         'product_name' => ($value['product_name'] ? $value['product_name'] : ''),
 437 |                         'barcode_id' => ($tempArr['code'] ? $value['code'] : ''),
 438 |                         'ingredients' => ($value['ingredients_text'] ? $value['ingredients_text'] : ''),
 439 |                         'saturated_fats' => ($value["nutriments"]["saturated-fat"] ? $value["nutriments"]["saturated-fat"] : 0),
 440 |                         'protein' => ($value["nutriments"]["proteins"] ? $value["nutriments"]["proteins"] : 0),
 441 |                         'sugar' => ($value["nutriments"]["sugars"] ? $value["nutriments"]["sugars"] : 0),
 442 |                         'salt' => ($value["nutriments"]["salt"] ? $value["nutriments"]["salt"] : 0),
 443 |                         'carbohydrate' => ($value["nutriments"]["carbohydrates"] ? $value["nutriments"]["carbohydrates"] : 0),
 444 |                         'dietary_fiber' => ($value["nutriments"]["fiber_value"] ? $value["nutriments"]["fiber_value"] : 0),
 445 |                         'sodium' => ($value["nutriments"]["sodium"] ? $value["nutriments"]["sodium"] : 0)
 446 |                     ];
 447 |                     if (!empty($product_array)) {
 448 |                         if (array_key_exists("image_url", $value)) {
 449 |                             $product_array['product_image'] = ($value["image_url"] ? $value["image_url"] : '');
 450 |                         }
 451 |                         if (array_key_exists("fat_amount", $value)) {
 452 |                             $product_array['fat_amount'] = ($value["nutriments"]["fat_amount"] ? $value["nutriments"]["fat_amount"] : '');
 453 |                         }
 454 |                     }
 455 |                 }
 456 |                 break;
 457 |         }
 458 |         return $product_array;
 459 |     }
 460 | 
 461 |     public function getUSAFoodDetails($product_name)
 462 |     {
 463 |         $product_array = [];
 464 |         $temp = -1;
 465 |         $skip = false;
 466 |         $selected_index = -1;
 467 |         $url = $_ENV['URL_USA_FOOD_API'] . $_ENV['USA_FOOD_KEY'] . '&query=' . urlencode($product_name);
 468 |         $tempArr = curlRequestLoad($url);
 469 | 
 470 |         if (!empty($tempArr['foods'])) {
 471 |             foreach ($tempArr['foods'] as $key => $value) {
 472 |                 $temp++;
 473 |                 if (!$skip && ($value["description"] == $product_name)
 474 |                     || (substr($value["description"], 0, strlen($product_name)) === $product_name)) {
 475 |                     $selected_index = $temp;
 476 |                     $skip = true;
 477 |                 }
 478 |             }
 479 |             if ($selected_index >= 0) {
 480 |                 $value = $tempArr['foods'][$selected_index];
 481 |             } else {
 482 |                 $value = $tempArr['foods'][0];
 483 |             }
 484 |             $product_array = [
 485 |                 'product_name' => $value["description"],
 486 |                 'ingredients' => ($value['ingredients'] ? $value['ingredients'] : '')
 487 |             ];
 488 |             $barcode = ($value['gtinUpc'] ? $value['gtinUpc'] : '');
 489 |             if ($barcode != '') {
 490 |                 $product_array['barcode_id'] = $barcode;
 491 |             }
 492 |             $objNutriments = $value['foodNutrients'];
 493 |             foreach ($objNutriments as $key) {
 494 |                 switch ($key['nutrientName']) {
 495 |                     case 'Fatty acids, total saturated"' :
 496 |                         $product_array['saturated_fats'] = $key['value'];
 497 |                         break;
 498 |                     case 'Protein' :
 499 |                         $product_array['protein'] = $key['value'];
 500 |                         break;
 501 |                     case 'Sugars, total including NLEA' :
 502 |                         $product_array['sugar'] = $key['value'];
 503 |                         break;
 504 |                     case 'Vitamin C, total ascorbic acid' :
 505 |                         $product_array['salt'] = $key['value'];
 506 |                         break;
 507 |                     case 'Carbohydrate, by difference' :
 508 |                         $product_array['carbohydrate'] = $key['value'];
 509 |                         break;
 510 |                     case 'Fiber, total dietary' :
 511 |                         $product_array['dietary_fiber'] = $key['value'];
 512 |                         break;
 513 |                     case 'Sodium, Na' :
 514 |                         $product_array['sodium'] = $key['value'];
 515 |                         break;
 516 |                     case 'Total lipid (fat)':
 517 |                         $product_array['fat_amount'] = $key['value'];
 518 |                         break;
 519 |                 }
 520 |             }
 521 |         }
 522 | 
 523 |         return $product_array;
 524 |     }
 525 | 
 526 |     public function getSwissFoodDetails($product_name)
 527 |     {
 528 |         $ch = curl_init();
 529 |         curl_setopt_array($ch, [
 530 |             CURLOPT_URL => $_ENV['URL_SWISS_FOOD_API'],
 531 |             CURLOPT_RETURNTRANSFER => true,
 532 |             CURLOPT_SSL_VERIFYPEER => false,
 533 |             CURLOPT_SSL_VERIFYHOST => 0,
 534 |             CURLOPT_CUSTOMREQUEST => "POST",
 535 |             CURLOPT_POSTFIELDS => "{\"query\":{\"query_string\":{\"query\":\"" . $product_name . "\"}}}",
 536 |             CURLOPT_HTTPHEADER => [
 537 |                 "Authorization: Token token=" . $_ENV['SWISS_FOOD_KEY'],
 538 |                 "Content-ApiProviders: application/vnd.api+json",
 539 |                 "Accept: application/json",
 540 |                 "Content-ApiProviders: application/json"
 541 |             ],
 542 |         ]);
 543 |         $result = curl_exec($ch);
 544 |         curl_close($ch);
 545 |         $tempArr = json_decode($result, true);
 546 |         $temp = -1;
 547 |         $skip = false;
 548 |         $selected_index = -1;
 549 |         $arrProducts = $tempArr['hits']["hits"];
 550 |         foreach ($arrProducts as $key => $value) {
 551 |             $temp++;
 552 |             $name = $value["_source"]["display_name_translations"]["en"];
 553 |             if (!$skip && ($name == $product_name)
 554 |                 || (substr($name, 0, strlen($product_name)) === $product_name)) {
 555 |                 $selected_index = $temp;
 556 |                 $skip = true;
 557 |             }
 558 |         }
 559 |         if ($selected_index >= 0) {
 560 |             $value = $arrProducts[$selected_index];
 561 |         } else {
 562 |             $value = $arrProducts[0];
 563 |         }
 564 |         $objProduct = $value["_source"];
 565 |         $product_array = [];
 566 |         foreach ($objProduct as $obj => $key) {
 567 |             switch ($obj) {
 568 |                 case 'barcode':
 569 |                     $product_array['barcode_id'] = $key;
 570 |                     break;
 571 |                 case 'alcohol_by_volume':
 572 |                     $product_array['alcohol'] = $key;
 573 |                     break;
 574 |                 case 'energy_kcal':
 575 |                     $product_array['calories'] = $key;
 576 |                     break;
 577 |                 case 'display_name_translations':
 578 |                     $product_array['product_name'] = $key['en'];
 579 |                     break;
 580 |                 case 'ingredients_translations':
 581 |                     $product_array['ingredients'] = $key['en'] ? $key['en'] : '';
 582 |                     break;
 583 |                 case 'images':
 584 |                     foreach ($objProduct[$obj] as $objImage => $keyImage) {
 585 |                         if ($keyImage['categories'][0] == 'Front') {
 586 |                             $product_array['product_image'] = $keyImage['medium'];
 587 |                         }
 588 |                     }
 589 |                     break;
 590 |                 case 'nutrients':
 591 |                     $objNutriments = $objProduct[$obj];
 592 |                     foreach ($objNutriments as $obj => $key) {
 593 |                         $value = $key['per_hundred'];
 594 |                         switch ($obj) {
 595 |                             case 'saturated_fat' :
 596 |                                 $product_array['saturated_fats'] = $value;
 597 |                                 break;
 598 |                             case 'protein' :
 599 |                                 $product_array['protein'] = $value;
 600 |                                 break;
 601 |                             case 'sugars' :
 602 |                                 $product_array['sugar'] = $value;
 603 |                                 break;
 604 |                             case 'salt' :
 605 |                                 $product_array['salt'] = $value;
 606 |                                 break;
 607 |                             case 'carbohydrates' :
 608 |                                 $product_array['carbohydrate'] = $value;
 609 |                                 break;
 610 |                             case 'fiber' :
 611 |                                 $product_array['dietary_fiber'] = $value;
 612 |                                 break;
 613 |                             case 'sodium' :
 614 |                                 $product_array['sodium'] = $value;
 615 |                                 break;
 616 |                             case 'fat':
 617 |                                 $product_array['fat_amount'] = $value;
 618 |                                 break;
 619 |                         }
 620 |                     }
 621 |                     break;
 622 |             }
 623 |         }
 624 |         return $product_array;
 625 |     }
 626 | 
 627 |     public function getProductDetailsV2($userData)
 628 |     {
 629 |         $connection = $this->connection;
 630 | 
 631 |         $user_id = validateObject($userData, 'user_id', '');
 632 |         $user_id = addslashes($user_id);
 633 | 
 634 |         $product_name = validateObject($userData, 'product_name', '');
 635 |         $product_name = utf8_decode($product_name);
 636 | 
 637 |         // 0 => Scan by productName, 1 => Scan by Barcode
 638 |         $flag = validateObject($userData, 'flag', 0);
 639 |         $flag = addslashes($flag);
 640 | 
 641 |         // 0 => Open Food , 1 => USA Food , 2 => Swiss Food
 642 |         $food_type = validateObject($userData, 'food_type', 0);
 643 |         $food_type = addslashes($food_type);
 644 | 
 645 |         $current_date = getDefaultDate();
 646 |         $is_favourite = 1;
 647 | 
 648 |         $select_product_details_stmt = getMultipleTableData(
 649 |             $connection,
 650 |             TABLE_PRODUCT,
 651 |             '',
 652 |             '*',
 653 |             '(LOWER(product_name) LIKE LOWER(:product_name) OR barcode_id = :barcode) AND is_delete = :is_delete ORDER BY created_date LIMIT 1',
 654 |             [
 655 |                 'product_name' => $product_name . '%',
 656 |                 'barcode' => $product_name,
 657 |                 'is_delete' => IS_DELETE
 658 |             ]
 659 |         );
 660 |         if ($select_product_details_stmt->rowCount() > 0) {
 661 |             $status = SUCCESS;
 662 |             while ($product = $select_product_details_stmt->fetch(PDO::FETCH_ASSOC)) {
 663 |                 $conditional_array = [
 664 |                     'product_id' => $product['id'],
 665 |                     'user_id' => $user_id,
 666 |                     'is_favourite' => $is_favourite,
 667 |                     'is_delete' => IS_DELETE,
 668 |                     'is_test' => IS_TESTDATA
 669 |                 ];
 670 |                 $objFavourite = getSingleTableData(
 671 |                     $connection,
 672 |                     TABLE_FAVOURITE,
 673 |                     '',
 674 |                     "id",
 675 |                     '',
 676 |                     $conditional_array
 677 |                 );
 678 |                 $product['is_favourite'] = !empty($objFavourite) ? 1 : 0;
 679 |                 $product_id = $product['id'];
 680 | 
 681 |                 $conditional_array = [
 682 |                     'product_id' => $product_id,
 683 |                     'user_id' => $user_id,
 684 |                     'is_delete' => IS_DELETE,
 685 |                     'is_test' => IS_TESTDATA
 686 |                 ];
 687 |                 $objHistory = getSingleTableData(
 688 |                     $connection,
 689 |                     TABLE_HISTORY,
 690 |                     '',
 691 |                     "id",
 692 |                     '',
 693 |                     $conditional_array
 694 |                 );
 695 |                 if (!empty($objHistory)) {
 696 |                     $history_id = $objHistory['id'];
 697 |                     $edit_history_response = editData(
 698 |                         $connection,
 699 |                         'getProductDetails',
 700 |                         TABLE_HISTORY,
 701 |                         ['created_date' => $current_date],
 702 |                         ['id' => $history_id, 'is_delete' => IS_DELETE, 'is_test' => IS_TESTDATA],
 703 |                         ''
 704 |                     );
 705 |                     if ($edit_history_response[STATUS_KEY] === SUCCESS) {
 706 |                         $posts[] = $product;
 707 |                         $data['status'] = SUCCESS;
 708 |                         $data['message'] = PRODUCT_FETCHED_SUCCESSFULLY;
 709 |                         $data['product'] = $posts;
 710 |                     } else {
 711 |                         $data['status'] = FAILED;
 712 |                         $data['message'] = SOMETHING_WENT_WRONG_TRY_AGAIN_LATER;
 713 |                     }
 714 |                     return $data;
 715 |                 } else {
 716 |                     $history_array = [
 717 |                         'user_id' => $user_id,
 718 |                         'product_id' => $product_id,
 719 |                         'created_date' => $current_date,
 720 |                         'is_test' => IS_TESTDATA
 721 |                     ];
 722 |                     $add_history_response = addData(
 723 |                         $connection,
 724 |                         '',
 725 |                         TABLE_HISTORY,
 726 |                         $history_array
 727 |                     );
 728 |                     if ($add_history_response[STATUS_KEY] === SUCCESS) {
 729 |                         $posts[] = $product;
 730 |                         $data['status'] = SUCCESS;
 731 |                         $data['message'] = PRODUCT_FETCHED_SUCCESSFULLY;
 732 |                         $data['product'] = $posts;
 733 |                     } else {
 734 |                         $data['status'] = FAILED;
 735 |                         $data['message'] = SOMETHING_WENT_WRONG_TRY_AGAIN_LATER;
 736 |                     }
 737 |                     return $data;
 738 |                 }
 739 |             }
 740 |         } else {
 741 |             //Create Product param to store product details
 742 |             $product_array = [];
 743 |             switch ($food_type) {
 744 |                 case ApiProviders::OPEN_FOOD_FACTS:
 745 |                     $product_array = $this->getOpenFoodDetails($product_name, $flag);
 746 |                     if (empty($product_array)) {
 747 |                         $product_array = $this->getUSAFoodDetails($product_name);
 748 |                         if (empty($product_array)) {
 749 |                             $product_array = $this->getSwissFoodDetails($product_name);
 750 |                         }
 751 |                     }
 752 |                     break;
 753 |                 case ApiProviders::FDC_USDA:
 754 |                     $product_array = $this->getUSAFoodDetails($product_name);
 755 |                     if (empty($product_array)) {
 756 |                         $product_array = $this->getSwissFoodDetails($product_name);
 757 |                         if (empty($product_array)) {
 758 |                             $product_array = $this->getOpenFoodDetails($product_name, $flag);
 759 |                         }
 760 |                     }
 761 |                     break;
 762 |                 case ApiProviders::FOOD_REPO:
 763 |                     $product_array = $this->getSwissFoodDetails($product_name);
 764 |                     print_r($product_array);
 765 |                     if (empty($product_array)) {
 766 |                         $product_array = $this->getOpenFoodDetails($product_name, $flag);
 767 |                         if (empty($product_array)) {
 768 |                             $product_array = $this->getUSAFoodDetails($product_name);
 769 |                         }
 770 |                     }
 771 |                     break;
 772 |             }
 773 |             if (!empty($product_array)) {
 774 |                 $product_array['is_delete'] = IS_DELETE;
 775 |                 $product_array['is_test'] = IS_TESTDATA;
 776 |                 $productDetails = $this->processProductDetails($product_array, $user_id);
 777 |                 if ($productDetails[STATUS_KEY] === SUCCESS) {
 778 |                     return $productDetails;
 779 |                 } else {
 780 |                     $data['status'] = $productDetails[STATUS_KEY];
 781 |                     $data['message'] = $productDetails[MESSAGE_KEY];
 782 |                     return $data;
 783 |                 }
 784 |             } else {
 785 |                 $data['status'] = FAILED;
 786 |                 $data['message'] = NO_PRODUCT_AVAILABLE;
 787 |                 return $data;
 788 |             }
 789 |         }
 790 |     }
 791 | 
 792 |     function processProductDetails($product_array, $user_id)
 793 |     {
 794 |         $connection = $this->connection;
 795 |         $current_date = getDefaultDate();
 796 | 
 797 |         $conditional_array_product = ['barcode_id' => $product_array['barcode_id'], 'is_delete' => IS_DELETE];
 798 |         $objProductData = getSingleTableData(
 799 |             $connection,
 800 |             TABLE_PRODUCT,
 801 |             '',
 802 |             "*",
 803 |             '',
 804 |             $conditional_array_product
 805 |         );
 806 |         if (!empty($objProductData)) {
 807 |             $objProductData['is_favourite'] = 0;
 808 |             $posts[] = $objProductData;
 809 |             $data['status'] = SUCCESS;
 810 |             $data['message'] = PRODUCT_FETCHED_SUCCESSFULLY;
 811 |             $data['product'] = $posts;
 812 |             return $data;
 813 |         } else {
 814 |             if ($product_array['product_name'] != '') {
 815 |                 $insert_response = addData(
 816 |                     $connection,
 817 |                     '',
 818 |                     TABLE_PRODUCT,
 819 |                     $product_array
 820 |                 );
 821 |                 if ($insert_response[STATUS_KEY] === SUCCESS) {
 822 |                     $last_inserted_id = $insert_response[MESSAGE_KEY];
 823 |                     $history_array = [
 824 |                         'user_id' => $user_id,
 825 |                         'product_id' => $last_inserted_id,
 826 |                         'created_date' => $current_date
 827 |                     ];
 828 |                     addData($connection, '', TABLE_HISTORY, $history_array);
 829 |                     $select = "select * from " . TABLE_PRODUCT . " where id=" . $last_inserted_id;
 830 |                     if ($stmt = $this->connection->prepare($select)) {
 831 |                         if ($stmt->execute()) {
 832 |                             if ($stmt->rowCount() > 0) {
 833 |                                 $status = SUCCESS;
 834 |                                 while ($product = $stmt->fetch(PDO::FETCH_ASSOC)) {
 835 |                                     $product['is_favourite'] = 0;
 836 |                                     $posts[] = $product;
 837 |                                 }
 838 |                             }
 839 |                         }
 840 |                         $stmt->closeCursor();
 841 |                         $data['status'] = SUCCESS;
 842 |                         $data['message'] = PRODUCT_FETCHED_SUCCESSFULLY;
 843 |                         $data['product'] = $posts;
 844 |                         return $data;
 845 |                     }
 846 |                 } else {
 847 |                     $data['status'] = FAILED;
 848 |                     $data['message'] = $insert_response[MESSAGE_KEY];
 849 |                     return $data;
 850 |                 }
 851 |             } else {
 852 |                 $data['status'] = FAILED;
 853 |                 $data['message'] = NO_PRODUCT_AVAILABLE;
 854 |                 return $data;
 855 |             }
 856 |         }
 857 |     }
 858 | 
 859 |     public function getProductDetails($userData)
 860 |     {
 861 |         $connection = $this->connection;
 862 | 
 863 |         $user_id = validateObject($userData, 'user_id', '');
 864 |         $user_id = addslashes($user_id);
 865 | 
 866 |         $product_name = validateObject($userData, 'product_name', '');
 867 |         $product_name = utf8_decode($product_name);
 868 | 
 869 |         $flag = validateObject($userData, 'flag', 0);
 870 |         $flag = addslashes($flag);
 871 | 
 872 |         $posts = [];
 873 |         $current_date = getDefaultDate();
 874 |         $message = '';
 875 |         $status = FAILED;
 876 |         $is_favourite = 1;
 877 | 
 878 |         $select_product_details_stmt = getMultipleTableData(
 879 |             $connection,
 880 |             TABLE_PRODUCT,
 881 |             '',
 882 |             '*',
 883 |             '(LOWER(product_name) LIKE LOWER(:product_name) OR barcode_id = :barcode) AND is_delete = :is_delete ORDER BY created_date LIMIT 1',
 884 |             [
 885 |                 'product_name' => $product_name . '%',
 886 |                 'barcode' => $product_name,
 887 |                 'is_delete' => IS_DELETE
 888 |             ]
 889 |         );
 890 |         if ($select_product_details_stmt->rowCount() > 0) {
 891 |             $status = SUCCESS;
 892 |             while ($product = $select_product_details_stmt->fetch(PDO::FETCH_ASSOC)) {
 893 |                 //get user favourite
 894 |                 $conditional_array = [
 895 |                     'product_id' => $product['id'],
 896 |                     'user_id' => $user_id,
 897 |                     'is_favourite' => $is_favourite,
 898 |                     'is_delete' => IS_DELETE,
 899 |                     'is_test' => IS_TESTDATA
 900 |                 ];
 901 |                 $objFavourite = getSingleTableData(
 902 |                     $connection,
 903 |                     TABLE_FAVOURITE,
 904 |                     '',
 905 |                     "id",
 906 |                     '',
 907 |                     $conditional_array
 908 |                 );
 909 |                 if (!empty($objFavourite)) {
 910 |                     $product['is_favourite'] = 1;
 911 |                 } else {
 912 |                     $product['is_favourite'] = 0;
 913 |                 }
 914 | 
 915 |                 //Product found in database insert data into history table
 916 |                 $product_id = $product['id'];
 917 |                 $conditional_array = [
 918 |                     'product_id' => $product_id,
 919 |                     'user_id' => $user_id,
 920 |                     'is_delete' => IS_DELETE,
 921 |                     'is_test' => IS_TESTDATA
 922 |                 ];
 923 |                 $objHistory = getSingleTableData(
 924 |                     $connection,
 925 |                     TABLE_HISTORY,
 926 |                     '',
 927 |                     "id",
 928 |                     '',
 929 |                     $conditional_array
 930 |                 );
 931 |                 if (!empty($objHistory)) {
 932 |                     $history_id = $objHistory['id'];
 933 |                     $edit_history_response = editData(
 934 |                         $connection,
 935 |                         'getProductDetails',
 936 |                         TABLE_HISTORY,
 937 |                         ['created_date' => $current_date],
 938 |                         ['id' => $history_id, 'is_delete' => IS_DELETE, 'is_test' => IS_TESTDATA],
 939 |                         ''
 940 |                     );
 941 |                     if ($edit_history_response[STATUS_KEY] === SUCCESS) {
 942 |                         $posts[] = $product;
 943 |                         $message = PRODUCT_FETCHED_SUCCESSFULLY;
 944 |                     } else {
 945 |                         $status = FAILED;
 946 |                         $message = SOMETHING_WENT_WRONG_TRY_AGAIN_LATER;
 947 |                         break;
 948 |                     }
 949 |                 } else {
 950 |                     $history_array = [
 951 |                         'user_id' => $user_id,
 952 |                         'product_id' => $product_id,
 953 |                         'created_date' => $current_date,
 954 |                         'is_test' => IS_TESTDATA
 955 |                     ];
 956 |                     $add_history_response = addData(
 957 |                         $connection,
 958 |                         '',
 959 |                         TABLE_HISTORY,
 960 |                         $history_array
 961 |                     );
 962 |                     if ($add_history_response[STATUS_KEY] === SUCCESS) {
 963 |                         $posts[] = $product;
 964 |                         $message = PRODUCT_FETCHED_SUCCESSFULLY;
 965 |                     } else {
 966 |                         $status = FAILED;
 967 |                         $message = SOMETHING_WENT_WRONG_TRY_AGAIN_LATER;
 968 |                         break;
 969 |                     }
 970 |                 }
 971 |             }
 972 |         } else {
 973 |             if ($flag == 0) {
 974 |                 $url = "https://ssl-api.openfoodfacts.org/cgi/search.pl?search_simple=1&json=1&action=process&fields=product_name,ingredients_text,codes_tags,image_url,nutriments,code&search_terms=" . urlencode(
 975 |                         $product_name
 976 |                     ) . "&page=1";
 977 |                 $ch = curl_init();
 978 |                 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
 979 |                 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
 980 |                 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
 981 |                 curl_setopt($ch, CURLOPT_URL, $url);
 982 | 
 983 |                 $result = curl_exec($ch);
 984 |                 curl_close($ch);
 985 |                 $tempArr = json_decode($result, true);
 986 |                 $temp = -1;
 987 |                 $skip = false;
 988 |                 $selected_index = -1;
 989 | 
 990 |                 if (count($tempArr['products']) > 0) {
 991 |                     foreach ($tempArr['products'] as $key => $value) {
 992 |                         $temp++;
 993 |                         if (!$skip && ($value["product_name"] == $product_name ||
 994 |                                 $this->startsWith($value["product_name"], $product_name))) {
 995 |                             $selected_index = $temp;
 996 |                             $skip = true;
 997 |                         }
 998 |                     }
 999 |                     if ($selected_index >= 0) {
1000 |                         $value = $tempArr['products'][$selected_index];
1001 |                     } else {
1002 |                         $value = $tempArr['products'][0];
1003 |                     }
1004 |                     $product_array = [
1005 |                         'barcode_id' => ($value['code'] ? $value['code'] : ''),
1006 |                         'product_name' => ($value['product_name'] ? $value['product_name'] : ''),
1007 |                         'is_delete' => IS_DELETE,
1008 |                         'is_test' => IS_TESTDATA,
1009 |                         'ingredients' => ($value['ingredients_text'] ? $value['ingredients_text'] : ''),
1010 |                         'saturated_fats' => ($value["nutriments"]["saturated-fat"] ? $value["nutriments"]["saturated-fat"] : 0),
1011 |                         'protein' => ($value["nutriments"]["proteins"] ? $value["nutriments"]["proteins"] : 0),
1012 |                         'sugar' => ($value["nutriments"]["sugars"] ? $value["nutriments"]["sugars"] : 0),
1013 |                         'salt' => ($value["nutriments"]["salt"] ? $value["nutriments"]["salt"] : 0),
1014 |                         'carbohydrate' => ($value["nutriments"]["carbohydrates"] ? $value["nutriments"]["carbohydrates"] : 0),
1015 |                         'dietary_fiber' => ($value["nutriments"]["fiber_value"] ? $value["nutriments"]["fiber_value"] : 0),
1016 |                         'sodium' => ($value["nutriments"]["sodium"] ? $value["nutriments"]["sodium"] : 0)
1017 |                     ];
1018 |                     if (!empty($product_array)) {
1019 |                         if (array_key_exists("image_url", $value)) {
1020 |                             $product_array['product_image'] = ($value["image_url"] ? $value["image_url"] : '');//validateValue($value['image_url'], '');
1021 |                         }
1022 |                         if (array_key_exists("fat_amount", $value)) {
1023 |                             $product_array['fat_amount'] = ($value["nutriments"]["fat_amount"] ? $value["nutriments"]["fat_amount"] : '');//$value["nutriments"]["fat_amount"];
1024 |                         }
1025 |                         $product_array['is_test'] = IS_TESTDATA;
1026 |                         $conditional_array_product = [
1027 |                             'barcode_id' => $product_array['barcode_id'],
1028 |                             'is_delete' => IS_DELETE
1029 |                         ];
1030 |                         $objProductData = getSingleTableData(
1031 |                             $connection,
1032 |                             TABLE_PRODUCT,
1033 |                             '',
1034 |                             "barcode_id",
1035 |                             '',
1036 |                             $conditional_array_product
1037 |                         );
1038 |                         if (!empty($objProductData)) {
1039 |                             $select = "select * from " . TABLE_PRODUCT . " where barcode_id= '" . $product_array['barcode_id'] . "' and is_delete = '" . IS_DELETE . "'";
1040 |                             if ($stmt = $this->connection->prepare($select)) {
1041 |                                 if ($stmt->execute()) {
1042 |                                     if ($stmt->rowCount() > 0) {
1043 |                                         $status = SUCCESS;
1044 |                                         while ($product = $stmt->fetch(PDO::FETCH_ASSOC)) {
1045 |                                             $product['is_favourite'] = 0;
1046 |                                             $posts[] = $product;
1047 |                                         }
1048 |                                     }
1049 |                                 }
1050 |                                 $stmt->closeCursor();
1051 |                                 $message = PRODUCT_FETCHED_SUCCESSFULLY;
1052 |                             }
1053 |                         } else {
1054 |                             $insert_response = addData(
1055 |                                 $connection,
1056 |                                 '',
1057 |                                 TABLE_PRODUCT,
1058 |                                 $product_array
1059 |                             );
1060 |                             if ($insert_response[STATUS_KEY] === SUCCESS) {
1061 |                                 $last_inserted_id = $insert_response[MESSAGE_KEY];
1062 |                                 //Insert data into history
1063 |                                 $history_array = [
1064 |                                     'user_id' => $user_id,
1065 |                                     'product_id' => $last_inserted_id,
1066 |                                     'created_date' => $current_date
1067 |                                 ];
1068 |                                 $add_history_response = addData(
1069 |                                     $connection,
1070 |                                     '',
1071 |                                     TABLE_HISTORY,
1072 |                                     $history_array
1073 |                                 );
1074 |                                 $select = "select * from " . TABLE_PRODUCT . " where id=" . $last_inserted_id;
1075 |                                 if ($stmt = $this->connection->prepare($select)) {
1076 |                                     if ($stmt->execute()) {
1077 |                                         if ($stmt->rowCount() > 0) {
1078 |                                             $status = SUCCESS;
1079 |                                             while ($product = $stmt->fetch(PDO::FETCH_ASSOC)) {
1080 |                                                 $product['is_favourite'] = 0;
1081 |                                                 $posts[] = $product;
1082 |                                             }
1083 |                                         }
1084 |                                     }
1085 |                                     $stmt->closeCursor();
1086 |                                     $message = PRODUCT_FETCHED_SUCCESSFULLY;
1087 |                                 }
1088 |                             } else {
1089 |                                 $message = $insert_response[MESSAGE_KEY];
1090 |                             }
1091 |                         }
1092 |                     } else {
1093 |                         $message = NO_PRODUCT_AVAILABLE;
1094 |                     }
1095 |                 } else {
1096 |                     $message = NO_PRODUCT_AVAILABLE;
1097 |                 }
1098 |             } else {
1099 |                 $url = "https://world.openfoodfacts.org/api/v0/product/" . urlencode($product_name) . ".json";
1100 |                 $ch = curl_init();
1101 |                 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
1102 |                 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
1103 |                 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
1104 |                 curl_setopt($ch, CURLOPT_URL, $url);
1105 | 
1106 |                 $result = curl_exec($ch);
1107 |                 curl_close($ch);
1108 |                 $tempArr = json_decode($result, true);
1109 |                 $temp = -1;
1110 |                 $skip = false;
1111 |                 $selected_index = -1;
1112 | 
1113 |                 if (count($tempArr['product']) > 0) {
1114 |                     $value = $tempArr['product'];
1115 |                     $product_array = [
1116 |                         'product_name' => ($value['product_name'] ? $value['product_name'] : ''),
1117 |                         'barcode_id' => ($tempArr['code'] ? $value['code'] : ''),
1118 |                         'is_delete' => IS_DELETE,
1119 |                         'is_test' => IS_TESTDATA,
1120 |                         'ingredients' => ($value['ingredients_text'] ? $value['ingredients_text'] : ''),
1121 |                         'saturated_fats' => ($value["nutriments"]["saturated-fat"] ? $value["nutriments"]["saturated-fat"] : 0),
1122 |                         'protein' => ($value["nutriments"]["proteins"] ? $value["nutriments"]["proteins"] : 0),
1123 |                         'sugar' => ($value["nutriments"]["sugars"] ? $value["nutriments"]["sugars"] : 0),
1124 |                         'salt' => ($value["nutriments"]["salt"] ? $value["nutriments"]["salt"] : 0),
1125 |                         'carbohydrate' => ($value["nutriments"]["carbohydrates"] ? $value["nutriments"]["carbohydrates"] : 0),
1126 |                         'dietary_fiber' => ($value["nutriments"]["fiber_value"] ? $value["nutriments"]["fiber_value"] : 0),
1127 |                         'sodium' => ($value["nutriments"]["sodium"] ? $value["nutriments"]["sodium"] : 0)
1128 |                     ];
1129 | 
1130 |                     if (!empty($product_array)) {
1131 |                         if (array_key_exists("image_url", $value)) {
1132 |                             $product_array['product_image'] = ($value["image_url"] ? $value["image_url"] : '');
1133 |                         }
1134 |                         if (array_key_exists("fat_amount", $value)) {
1135 |                             $product_array['fat_amount'] = ($value["nutriments"]["fat_amount"] ? $value["nutriments"]["fat_amount"] : '');
1136 |                         }
1137 |                         $product_array['is_test'] = IS_TESTDATA;
1138 |                         if ($value['product_name'] != '') {
1139 |                             $conditional_array_product = [
1140 |                                 'barcode_id' => $product_array['barcode_id'],
1141 |                                 'is_delete' => IS_DELETE
1142 |                             ];
1143 |                             $objProductData = getSingleTableData(
1144 |                                 $connection,
1145 |                                 TABLE_PRODUCT,
1146 |                                 '',
1147 |                                 "barcode_id",
1148 |                                 '',
1149 |                                 $conditional_array_product
1150 |                             );
1151 |                             if (!empty($objProductData)) {
1152 |                                 $select = "select * from " . TABLE_PRODUCT . " where barcode_id= '" . $product_array['barcode_id'] . "' and is_delete = '" . IS_DELETE . "'";
1153 |                                 if ($stmt = $this->connection->prepare($select)) {
1154 |                                     if ($stmt->execute()) {
1155 |                                         if ($stmt->rowCount() > 0) {
1156 |                                             $status = SUCCESS;
1157 |                                             while ($product = $stmt->fetch(PDO::FETCH_ASSOC)) {
1158 |                                                 $product['is_favourite'] = 0;
1159 |                                                 $posts[] = $product;
1160 |                                             }
1161 |                                         }
1162 |                                     }
1163 |                                     $stmt->closeCursor();
1164 |                                     $message = PRODUCT_FETCHED_SUCCESSFULLY;
1165 |                                 }
1166 |                             } else {
1167 |                                 $insert_response = addData(
1168 |                                     $connection,
1169 |                                     '',
1170 |                                     TABLE_PRODUCT,
1171 |                                     $product_array
1172 |                                 );
1173 |                                 if ($insert_response[STATUS_KEY] === SUCCESS) {
1174 |                                     $last_inserted_id = $insert_response[MESSAGE_KEY];
1175 |                                     //Insert data into history
1176 |                                     $history_array = [
1177 |                                         'user_id' => $user_id,
1178 |                                         'product_id' => $last_inserted_id,
1179 |                                         'created_date' => $current_date
1180 |                                     ];
1181 |                                     $add_history_response = addData($connection, '', TABLE_HISTORY, $history_array);
1182 |                                     $select = "select * from " . TABLE_PRODUCT . " where id=" . $last_inserted_id;
1183 |                                     if ($stmt = $this->connection->prepare($select)) {
1184 |                                         if ($stmt->execute()) {
1185 |                                             if ($stmt->rowCount() > 0) {
1186 |                                                 $status = SUCCESS;
1187 |                                                 while ($product = $stmt->fetch(PDO::FETCH_ASSOC)) {
1188 |                                                     $product['is_favourite'] = 0;
1189 |                                                     $posts[] = $product;
1190 |                                                 }
1191 |                                             }
1192 |                                         }
1193 |                                         $stmt->closeCursor();
1194 |                                         $message = PRODUCT_FETCHED_SUCCESSFULLY;
1195 |                                     }
1196 |                                 } else {
1197 |                                     $message = $insert_response[MESSAGE_KEY];
1198 |                                 }
1199 |                             }
1200 |                         } else {
1201 |                             $message = NO_PRODUCT_AVAILABLE;
1202 |                         }
1203 |                     } else {
1204 |                         $message = NO_PRODUCT_AVAILABLE;
1205 |                     }
1206 |                 } else {
1207 |                     $message = NO_PRODUCT_AVAILABLE;
1208 |                 }
1209 |             }
1210 |         }
1211 |         $select_product_details_stmt->closeCursor();
1212 |         $data['status'] = $status;
1213 |         $data['message'] = $message;
1214 |         $data['product'] = $posts;
1215 |         return $data;
1216 |     }
1217 | 
1218 |     public function removeProductFromHistory($userData)
1219 |     {
1220 |         $connection = $this->connection;
1221 |         $history_id = validateObject($userData, 'history_id', '');
1222 |         $history_id = addslashes($history_id);
1223 | 
1224 |         $edit_history_response = editData(
1225 |             $connection,
1226 |             "removeProductFromHistory",
1227 |             TABLE_HISTORY,
1228 |             ['is_delete' => DELETE_STATUS::IS_DELETE],
1229 |             ['id' => $history_id, 'is_test' => IS_TESTDATA],
1230 |             ''
1231 |         );
1232 |         if ($edit_history_response[STATUS_KEY] === SUCCESS) {
1233 |             $objHistory = getSingleTableData(
1234 |                 $connection,
1235 |                 TABLE_HISTORY,
1236 |                 '',
1237 |                 '*',
1238 |                 '',
1239 |                 ['id' => $history_id, 'is_test' => IS_TESTDATA, 'is_delete' => IS_DELETE]
1240 |             );
1241 |             if (!empty($objHistory)) {
1242 |                 $conditional_array = [
1243 |                     'product_id' => $objHistory['product_id'],
1244 |                     'user_id' => $objHistory['user_id'],
1245 |                     'is_test' => IS_TESTDATA
1246 |                 ];
1247 |                 editData(
1248 |                     $connection,
1249 |                     "addToFavourite",
1250 |                     TABLE_FAVOURITE,
1251 |                     ['is_favourite' => $is_favourite = '0'],
1252 |                     $conditional_array,
1253 |                     ''
1254 |                 );
1255 |             }
1256 |             $message = HISTORY_REMOVED_SUCCESSFULLY;
1257 |             $status = SUCCESS;
1258 |         } else {
1259 |             $status = FAILED;
1260 |             $message = SOMETHING_WENT_WRONG_TRY_AGAIN_LATER;
1261 |         }
1262 |         $data['status'] = $status;
1263 |         $data['message'] = $message;
1264 |         return $data;
1265 |     }
1266 | 
1267 |     public function getUserHistory($userData)
1268 |     {
1269 |         $connection = $this->connection;
1270 | 
1271 |         $user_id = validateObject($userData, 'user_id', '');
1272 |         $user_id = addslashes($user_id);
1273 | 
1274 |         $to_index = validateObject($userData, 'to_index', '');
1275 |         $to_index = addslashes($to_index);
1276 | 
1277 |         $from_index = validateObject($userData, 'from_index', '');
1278 |         $from_index = addslashes($from_index);
1279 | 
1280 |         $posts = [];
1281 | 
1282 |         $select_user_history_query = "SELECT h.id as history_id, h.user_id, h.product_id, h.created_date AS history_created_date , p.* FROM history AS h
1283 |                                       LEFT JOIN product AS p ON p.id = h.product_id
1284 |                                       WHERE h.user_id = :user_id AND h.is_delete = :is_delete
1285 |                                     AND p.is_delete = :is_delete AND h.is_test = '" . IS_TESTDATA . "'  
1286 |                                     AND p.product_name != '' ORDER BY h.created_date DESC limit $from_index,$to_index ";
1287 |         $conditional_array = ['user_id' => $user_id, 'is_delete' => IS_DELETE];
1288 |         $select_user_history_stmt = getMultipleTableData(
1289 |             $connection,
1290 |             '',
1291 |             $select_user_history_query,
1292 |             '',
1293 |             '',
1294 |             $conditional_array
1295 |         );
1296 |         if ($select_user_history_stmt->rowCount() > 0) {
1297 |             while ($history = $select_user_history_stmt->fetch(PDO::FETCH_ASSOC)) {
1298 |                 $select_total_review_query = "SELECT COUNT(*) AS total_review, avg(ratting) AS avg_review FROM " . TABLE_REVIEW . " r WHERE product_id = '" . $history['product_id'] . "' AND is_test = '" . IS_TESTDATA . "' AND is_delete = '" . IS_DELETE . "'";
1299 |                 $select_total_review_stmt = getSingleTableData(
1300 |                     $connection,
1301 |                     '',
1302 |                     $select_total_review_query,
1303 |                     '',
1304 |                     '',
1305 |                     ''
1306 |                 );
1307 |                 if (!empty($select_total_review_stmt)) {
1308 |                     $history['total_review'] = $select_total_review_stmt['total_review'];
1309 |                     $history['avg_review'] = $select_total_review_stmt['avg_review'];
1310 |                 }
1311 |                 //get user favourite
1312 |                 $is_favourite = 1;
1313 |                 $conditional_array = [
1314 |                     'product_id' => $history['product_id'],
1315 |                     'user_id' => $user_id,
1316 |                     'is_favourite' => $is_favourite,
1317 |                     'is_delete' => IS_DELETE,
1318 |                     'is_test' => IS_TESTDATA
1319 |                 ];
1320 |                 $objFavourite = getSingleTableData(
1321 |                     $connection,
1322 |                     TABLE_FAVOURITE,
1323 |                     '',
1324 |                     "id",
1325 |                     '',
1326 |                     $conditional_array
1327 |                 );
1328 |                 if (!empty($objFavourite)) {
1329 |                     $history['is_favourite'] = '1';
1330 |                 } else {
1331 |                     $history['is_favourite'] = '0';
1332 |                 }
1333 |                 $posts[] = $history;
1334 |             }
1335 |             $message = DATA_FETCHED_SUCCESSFULLY;
1336 |             $status = SUCCESS;
1337 |         } else {
1338 |             $status = SUCCESS;
1339 |             $message = NO_FAVOURITE_HISTORY_FOUND;
1340 |         }
1341 |         $data['status'] = $status;
1342 |         $data['message'] = $message;
1343 |         $data['history'] = $posts;
1344 |         return $data;
1345 |     }
1346 | 
1347 |     public function getAllUserFavourite($userData)
1348 |     {
1349 |         $connection = $this->connection;
1350 | 
1351 |         $user_id = validateObject($userData, 'user_id', '');
1352 |         $user_id = addslashes($user_id);
1353 | 
1354 |         $to_index = validateObject($userData, 'to_index', '');
1355 |         $to_index = addslashes($to_index);
1356 | 
1357 |         $from_index = validateObject($userData, 'from_index', '');
1358 |         $from_index = addslashes($from_index);
1359 | 
1360 |         $posts = [];
1361 |         $is_favourite = 1;
1362 | 
1363 |         $select_user_favourite_query = "SELECT f.id as favourite_id , f.user_id, f.product_id, f.is_favourite, f.created_date AS favourite_created_date , p.* FROM " . TABLE_FAVOURITE . " AS f
1364 |                                         LEFT JOIN " . TABLE_PRODUCT . " AS p ON p.id = f.product_id
1365 |                                         WHERE f.user_id = " . $user_id . " AND f.is_favourite = '" . $is_favourite . "'
1366 |                                         AND f.is_test = '" . IS_TESTDATA . "'  AND f.is_delete = '" . IS_DELETE . "' 
1367 |                                         AND p.is_delete = '" . IS_DELETE . "'
1368 |                                         AND p.product_name != '' ORDER BY f.created_date DESC limit $from_index,$to_index ";
1369 |         $select_user_favourite_stmt = getMultipleTableData(
1370 |             $connection,
1371 |             '',
1372 |             $select_user_favourite_query,
1373 |             '',
1374 |             '',
1375 |             []
1376 |         );
1377 |         if ($select_user_favourite_stmt->rowCount() > 0) {
1378 |             while ($product = $select_user_favourite_stmt->fetch(PDO::FETCH_ASSOC)) {
1379 |                 $select_total_review_query = "Select count(*) as total_review, avg(ratting) as avg_review from " . TABLE_REVIEW . " r 
1380 |                 where product_id = '" . $product['product_id'] . "' 
1381 |                 and is_test = '" . IS_TESTDATA . "' and is_delete = '" . IS_DELETE . "'";
1382 |                 $select_total_review_stmt = getSingleTableData(
1383 |                     $connection,
1384 |                     '',
1385 |                     $select_total_review_query,
1386 |                     '',
1387 |                     '',
1388 |                     ''
1389 |                 );
1390 |                 if (!empty($select_total_review_stmt)) {
1391 |                     $product['total_review'] = $select_total_review_stmt['total_review'];
1392 |                     $product['avg_review'] = $select_total_review_stmt['avg_review'];
1393 |                 }
1394 |                 $posts[] = $product;
1395 |             }
1396 |             $status = SUCCESS;
1397 |             $message = DATA_FETCHED_SUCCESSFULLY;
1398 |         } else {
1399 |             $status = SUCCESS;
1400 |             $message = NO_FAVOURITE_PRODUCT_FOUND;
1401 |         }
1402 |         $data['status'] = $status;
1403 |         $data['message'] = $message;
1404 |         $data['product'] = $posts;
1405 |         return $data;
1406 |     }
1407 | 
1408 |     public function addToFavourite($userData)
1409 |     {
1410 |         $connection = $this->connection;
1411 | 
1412 |         $user_id = validateObject($userData, 'user_id', '');
1413 |         $user_id = addslashes($user_id);
1414 | 
1415 |         $product_id = validateObject($userData, 'product_id', '');
1416 |         $product_id = addslashes($product_id);
1417 | 
1418 |         $is_favourite = validateObject($userData, 'is_favourite', '');
1419 |         $is_favourite = addslashes($is_favourite);
1420 | 
1421 |         $is_rate = false;
1422 |         $current_date = date(DATETIME_FORMAT);
1423 | 
1424 |         $conditional_array = [
1425 |             'product_id' => $product_id,
1426 |             'user_id' => $user_id,
1427 |             'is_delete' => IS_DELETE,
1428 |             'is_test' => IS_TESTDATA
1429 |         ];
1430 |         $objFavourite = getSingleTableData(
1431 |             $connection,
1432 |             TABLE_FAVOURITE,
1433 |             '',
1434 |             "id,is_favourite",
1435 |             '',
1436 |             $conditional_array
1437 |         );
1438 | 
1439 |         if (!empty($objFavourite)) {
1440 |             $edit_response = editData(
1441 |                 $connection,
1442 |                 "addToFavourite",
1443 |                 TABLE_FAVOURITE,
1444 |                 ['is_favourite' => $is_favourite, 'created_date' => $current_date],
1445 |                 ['id' => $objFavourite['id']],
1446 |                 ''
1447 |             );
1448 |             if ($edit_response[STATUS_KEY] === SUCCESS) {
1449 |                 $status = SUCCESS;
1450 |                 $message = $is_favourite == 1 ? FAVOURITE_SUCCESSFULLY : REMOVE_FAVOURITE_SUCCESSFULLY;
1451 |             } else {
1452 |                 $status = FAILED;
1453 |                 $message = SOMETHING_WENT_WRONG_TRY_AGAIN_LATER;
1454 |             }
1455 |         } else {
1456 |             $favourite_product_array = [
1457 |                 'user_id' => $user_id,
1458 |                 'product_id' => $product_id,
1459 |                 'is_favourite' => $is_favourite,
1460 |                 'created_date' => $current_date,
1461 |                 'is_test' => IS_TESTDATA
1462 |             ];
1463 |             $favourite_response = addData(
1464 |                 $connection,
1465 |                 "addToFavourite",
1466 |                 TABLE_FAVOURITE,
1467 |                 $favourite_product_array
1468 |             );
1469 |             if ($favourite_response[STATUS_KEY] === SUCCESS) {
1470 |                 $status = SUCCESS;
1471 |                 $message = FAVOURITE_SUCCESSFULLY;
1472 |             } else {
1473 |                 $status = FAILED;
1474 |                 $message = SOMETHING_WENT_WRONG_TRY_AGAIN_LATER;
1475 |             }
1476 |         }
1477 |         //START : Check if user have added 5 or more product as favourite then  rate status will as true else false.
1478 |         if ($status === SUCCESS) {
1479 |             $rate_status = $this->isUserRate($user_id);
1480 |             if ($rate_status === SUCCESS) {
1481 |                 $select_user_fav_query = "SELECT count(*) as count_fav from " . TABLE_FAVOURITE . " WHERE user_id = " . $user_id . " 
1482 |                                     AND is_favourite = '1'
1483 |                                     AND is_test = '" . IS_TESTDATA . "' AND is_delete = '" . IS_DELETE . "' ";
1484 |                 $select_user_fav_stmt = getSingleTableData(
1485 |                     $connection,
1486 |                     '',
1487 |                     $select_user_fav_query,
1488 |                     '',
1489 |                     '',
1490 |                     []
1491 |                 );
1492 |                 if (!empty($select_user_fav_stmt) && $select_user_fav_stmt['count_fav'] >= 5) {
1493 |                     $is_rate = true;
1494 |                 } else {
1495 |                     $is_rate = false;
1496 |                 }
1497 |             } else {
1498 |                 $is_rate = false;
1499 |             }
1500 |         }
1501 |         //END
1502 |         $data['is_rate'] = $is_rate;
1503 |         $data['status'] = $status;
1504 |         $data['message'] = $message;
1505 |         return $data;
1506 |     }
1507 | 
1508 |     public function isUserRate($user_id): string
1509 |     {
1510 |         $connection = $this->connection;
1511 |         $select_user_rated_query = "SELECT * from " . TABLE_RATING . " WHERE user_id = " . $user_id . " 
1512 |                                     AND is_rate = '1'
1513 |                                     AND device_type = (SELECT device_type from " . TABLE_USER . " WHERE id = " . $user_id . " AND is_test = '" . IS_TESTDATA . "' and is_delete = '" . IS_DELETE . "') 
1514 |                                     AND is_test = '" . IS_TESTDATA . "' AND is_delete = '" . IS_DELETE . "' ";
1515 |         $select_user_rated_stmt = getSingleTableData(
1516 |             $connection,
1517 |             '',
1518 |             $select_user_rated_query,
1519 |             '',
1520 |             '',
1521 |             []
1522 |         );
1523 |         if (!empty($select_user_rated_stmt)) {
1524 |             $status = FAILED;
1525 |         } else {
1526 |             $status = SUCCESS;
1527 |         }
1528 |         return $status;
1529 |     }
1530 | 
1531 | }
1532 | 


--------------------------------------------------------------------------------
/src/Security.php:
--------------------------------------------------------------------------------
  1 | connection = $con;
 18 |     }
 19 | 
 20 |     public function callService($service, $postData)
 21 |     {
 22 |         switch ($service) {
 23 |             case self::REFRESH_TOKEN:
 24 |                 return $this->refreshToken($postData);
 25 | 
 26 |             case self::TEST_ENCRYPTION:
 27 |                 return $this->testEncryption($postData);
 28 | 
 29 |             case self::UPDATE_USER_TOKEN:
 30 |                 return $this->updateTokenForUser($postData);
 31 | 
 32 |             case self::EXPIRED_ALL_USER_TOKEN:
 33 |                 return $this->expiredAllTokenOfUser($postData);
 34 | 
 35 |             default:
 36 |                 return null;
 37 |         }
 38 |     }
 39 | 
 40 |     //Generate Random Unique Token Number
 41 |     public function crypto_random_secure($min, $max)
 42 |     {
 43 |         $range = $max - $min;
 44 |         if ($range < 1) return $min; // not so random...
 45 |         $log = ceil(log($range, 2));
 46 |         $bytes = (int)($log / 8) + 1; // length in bytes
 47 |         $bits = (int)$log + 1; // length in bits
 48 |         $filter = (int)(1 << $bits) - 1; // set all lower bits to 1
 49 |         do {
 50 |             $rnd = hexdec(bin2hex(openssl_random_pseudo_bytes($bytes)));
 51 |             $rnd = $rnd & $filter; // discard irrelevant bits
 52 |         } while ($rnd >= $range);
 53 |         return $min + $rnd;
 54 |     }
 55 | 
 56 |     public function updateTokenForUser($userData)
 57 |     {
 58 |         $connection = $this->connection;
 59 |         $user_id = validateObject($userData, 'user_id', "");
 60 |         $user_id = addslashes($user_id);
 61 | 
 62 |         if ($user_id != '') {
 63 |             $modifiedDate = date(DATETIME_FORMAT, time());
 64 |             $generateToken = $this->generateToken(8);
 65 |             $objExpiryDate = getSingleTableData(
 66 |                 $connection,
 67 |                 TABLE_ADMIN_CONFIG,
 68 |                 '',
 69 |                 'config_value',
 70 |                 '',
 71 |                 ['config_key' => 'expiry_duration', 'is_delete' => DELETE_STATUS::NOT_DELETE]
 72 |             );
 73 |             if (!empty($objExpiryDate)) {
 74 |                 $expiryDuration = $objExpiryDate['config_value'];
 75 |                 $currentDate = date("dmyHis", time() + $expiryDuration);
 76 |                 $token_array = [
 77 |                     ':userid' => $user_id,
 78 |                     ':token' => $generateToken,
 79 |                     ':expiry' => $currentDate,
 80 |                     ':token1' => $generateToken,
 81 |                     ':expiry1' => $currentDate,
 82 |                     ':created_date' => $modifiedDate
 83 |                 ];
 84 |                 error_reporting(E_ALL & ~E_NOTICE);
 85 |                 $insertUpdateQuery = "INSERT INTO " . TABLE_APP_TOKENS . " (userid,token,expiry) VALUES(:userid,:token,:expiry)
 86 |             ON DUPLICATE KEY UPDATE token = :token1 , expiry = :expiry1, created_date = :created_date";
 87 | 
 88 |                 if ($stmt = $connection->prepare($insertUpdateQuery)) {
 89 |                     if ($stmt->execute($token_array)) {
 90 |                         $stmt->closeCursor();
 91 |                         $uuid = validateObject($userData, 'GUID', "");
 92 |                         $uuid = addslashes($uuid);
 93 |                         $security = new ApiCrypter();
 94 |                         $objGlobalPassword = getSingleTableData($connection, TABLE_ADMIN_CONFIG, "", "config_value", "", ['config_key' => 'globalPassword', 'is_delete' => DELETE_STATUS::NOT_DELETE]);
 95 |                         if (!empty($objGlobalPassword)) {
 96 |                             $masterKey = $objGlobalPassword['config_value'];
 97 |                             $data['GUID'] = $userData->GUID;
 98 |                             $data['masterKey'] = $masterKey;
 99 |                             $data['acessKey'] = $security->encrypt($uuid, $masterKey);
100 |                         }
101 |                         $generateTokenEncrypted = $security->encrypt($generateToken, $uuid);
102 |                         $currentDateEncrypted = $security->encrypt($currentDate, $uuid);
103 |                         $encryptedTokenName = $generateTokenEncrypted . '_' . $currentDateEncrypted;//$security->encrypt($mixedToken, $uuid."_".$username);
104 |                         $data[USERTOKEN] = $encryptedTokenName;
105 |                         $data['status'] = SUCCESS;
106 |                         return $data;
107 |                     } else {
108 |                         $data['status'] = FAILED;
109 |                         $data[USERTOKEN] = NO;
110 |                         return $data;
111 |                     }
112 |                 } else {
113 |                     $data['status'] = FAILED;
114 |                     $data[USERTOKEN] = NO;
115 |                     return $data;
116 |                 }
117 |             } else {
118 |                 $data[STATUS_KEY] = FAILED;
119 |                 $data[USERTOKEN] = NO;
120 |                 return $data;
121 |             }
122 |         }
123 |         $data[STATUS_KEY] = FAILED;
124 |         $data[USERTOKEN] = NO;
125 |         return $data;
126 |     }
127 | 
128 |     public function updateTokenForUserLogin($userData)
129 |     {
130 |         $connection = $this->connection;
131 |         $user_id = validateValue($userData->userId, '');
132 | 
133 |         if ($user_id != '') {
134 |             $modifiedDate = date(DATETIME_FORMAT, time());
135 |             $generateToken = $this->generateToken(8);
136 |             $objExpiryDate = getSingleTableData($connection, TABLE_ADMIN_CONFIG, "", "config_value", "", ['config_key' => 'expiry_duration', 'is_delete' => DELETE_STATUS::NOT_DELETE]);
137 |             if (!empty($objExpiryDate)) {
138 |                 $expiryDuration = $objExpiryDate['config_value'];
139 |                 $currentDate = date("dmyHis", time() + $expiryDuration);
140 |                 $token_array = [':userid' => $user_id, ':token' => $generateToken,
141 |                     ':expiry' => $currentDate, ':token1' => $generateToken, ':expiry1' => $currentDate, ':created_date' => $modifiedDate];
142 |                 error_reporting(E_ALL & ~E_NOTICE);
143 |                 $insertUpdateQuery = "INSERT INTO " . TABLE_APP_TOKENS . " (userid,token,expiry) VALUES(:userid,:token,:expiry)
144 |             ON DUPLICATE KEY UPDATE token = :token1 , expiry = :expiry1, created_date = :created_date";
145 | 
146 |                 if ($stmt = $connection->prepare($insertUpdateQuery)) {
147 |                     if ($stmt->execute($token_array)) {
148 |                         $stmt->closeCursor();
149 |                         $uuid = validateValue($userData->GUID, '');
150 |                         $security = new ApiCrypter();
151 | 
152 |                         $objGlobalPassword = getSingleTableData($connection, TABLE_ADMIN_CONFIG, "", "config_value", "", ['config_key' => 'globalPassword', 'is_delete' => DELETE_STATUS::NOT_DELETE]);
153 |                         if (!empty($objGlobalPassword)) {
154 |                             $masterKey = $objGlobalPassword['config_value'];
155 |                             $data['GUID'] = $userData->GUID;
156 |                             $data['masterKey'] = $masterKey;
157 |                             $data['acessKey'] = $security->encrypt($uuid, $masterKey);
158 |                         }
159 |                         $generateTokenEncrypted = $security->encrypt($generateToken, $uuid);
160 |                         $currentDateEncrypted = $security->encrypt($currentDate, $uuid);
161 |                         $encryptedTokenName = $generateTokenEncrypted . '_' . $currentDateEncrypted;//$security->encrypt($mixedToken, $uuid."_".$username);
162 |                         $data[USERTOKEN] = $encryptedTokenName;
163 |                         $data['status'] = SUCCESS;
164 |                         return $data;
165 |                     } else {
166 |                         $data['status'] = FAILED;
167 |                         $data[USERTOKEN] = NO;
168 |                         return $data;
169 |                     }
170 |                 } else {
171 |                     $data['status'] = FAILED;
172 |                     $data[USERTOKEN] = NO;
173 |                     return $data;
174 |                 }
175 |             } else {
176 |                 $data[STATUS_KEY] = FAILED;
177 |                 $data[USERTOKEN] = NO;
178 |                 return $data;
179 |             }
180 |         }
181 |         $data[STATUS_KEY] = FAILED;
182 |         $data[USERTOKEN] = NO;
183 |         return $data;
184 |     }
185 | 
186 |     public function generateUniqueId()
187 |     {
188 |         return sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x',
189 |             mt_rand(0, 0xffff), mt_rand(0, 0xffff),
190 |             mt_rand(0, 0xffff),
191 |             mt_rand(0, 0x0fff) | 0x4000,
192 |             mt_rand(0, 0x3fff) | 0x8000,
193 |             mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff)
194 |         );
195 |     }
196 | 
197 |     public function checkForSecurityNew($accessValue, $secretValue)
198 |     {
199 |         $connection = $this->connection;
200 |         if ($accessValue == "" || $secretValue == "") {
201 |             return ERROR;
202 |         } else {
203 |             $objUserAgent = getSingleTableData($connection, TABLE_ADMIN_CONFIG, "", "config_value", "", ['config_key' => 'userAgent', 'is_delete' => DELETE_STATUS::NOT_DELETE]);
204 |             if (!empty($objUserAgent)) {
205 |                 $user_agent = $objUserAgent['config_value'];
206 |                 $separateKey = (explode(',', $user_agent));
207 |                 if ((strpos($_SERVER ['HTTP_USER_AGENT'], $separateKey[0]) !== false) || (strpos($_SERVER ['HTTP_USER_AGENT'], $separateKey[1]) !== false) || (strpos($_SERVER ['HTTP_USER_AGENT'], $separateKey[2]) !== false) || (strpos($_SERVER ['HTTP_USER_AGENT'], $separateKey[3]) !== false) || (strpos($_SERVER ['HTTP_USER_AGENT'], $separateKey[4]) !== false) || (strpos($_SERVER ['HTTP_USER_AGENT'], $separateKey[5]) !== false) || (strpos($_SERVER ['HTTP_USER_AGENT'], $separateKey[6]) !== false)) {
208 |                     $getTempToken = getSingleTableData($connection, TABLE_ADMIN_CONFIG, "", "config_value", "", ['config_key' => 'tempToken', 'is_delete' => DELETE_STATUS::NOT_DELETE]);
209 |                     if (!empty($getTempToken)) {
210 |                         $tempToken = $getTempToken['config_value'];
211 |                         $objGlobalPassword = getSingleTableData($connection, TABLE_ADMIN_CONFIG, "", "config_value", "", ['config_key' => 'globalPassword', 'is_delete' => DELETE_STATUS::NOT_DELETE]);
212 |                         if (!empty($objGlobalPassword)) {
213 |                             $masterKey = $objGlobalPassword['config_value'];
214 |                             $security = new ApiCrypter();
215 |                             if ($accessValue === 'nousername') {
216 |                                 if ($secretValue == null) {
217 |                                     $secretValue = $security->encrypt($tempToken, $masterKey);
218 |                                     $response = [];
219 |                                     $response['key'] = "Temp";// return temporary token
220 |                                     $response['value'] = $secretValue;
221 |                                     return $response;
222 |                                 } else {
223 |                                     $secretValue1 = $security->encrypt($tempToken, $masterKey);
224 |                                     if (trim($secretValue1) == trim($secretValue)) {
225 |                                         return YES;
226 |                                     } else {
227 |                                         return NO;
228 |                                     }
229 |                                 }
230 |                             } else {
231 |                                 $tempToken = $security->encrypt($tempToken, $masterKey);
232 |                                 return $this->checkCredentialsForSecurityNew($accessValue, $secretValue, $tempToken);
233 |                             }
234 |                         }
235 |                     }
236 |                 }
237 |             }
238 |         }
239 |         return NO;
240 |     }
241 | 
242 |     public function checkCredentialsForSecurityNew($accessValue, $secretValue, $tempToken)
243 |     {
244 |         $connection = $this->connection;
245 |         $objGlobalPassword = getSingleTableData($connection, TABLE_ADMIN_CONFIG, "", "config_value", "", ['config_key' => 'globalPassword', 'is_delete' => DELETE_STATUS::NOT_DELETE]);
246 |         if (!empty($objGlobalPassword)) {
247 |             $masterKey = $objGlobalPassword['config_value'];
248 |             $security = new ApiCrypter();
249 |             $decrypted_access_key = $security->decrypt($accessValue, $masterKey);
250 |             $objUser = getSingleTableData($connection, TABLE_USER, "", "id", "", ['guid' => $decrypted_access_key, 'is_delete' => DELETE_STATUS::NOT_DELETE]);
251 |             if (!empty($objUser)) {
252 |                 $row_token = getSingleTableDataLastDate($connection, TABLE_APP_TOKENS, "", "token,expiry", "", ['userid' => $objUser['id'], 'is_delete' => DELETE_STATUS::NOT_DELETE]);
253 |                 if (!empty($row_token)) {
254 |                     $tokenName = $row_token['token'];
255 |                     $currentDate = $row_token['expiry'];
256 |                     if ($secretValue == $tempToken) {
257 |                         $currentDateEncrypt = $security->encrypt($currentDate, $decrypted_access_key);
258 |                         $tokenNameEncrypt = $security->encrypt($tokenName, $decrypted_access_key);
259 |                         $tokenName = $tokenNameEncrypt . '_' . $currentDateEncrypt;
260 |                         $response = [];
261 |                         $response['key'] = 'User'; // return user's private token
262 |                         $response['value'] = $tokenName;
263 |                         return $response;
264 |                     } elseif ($secretValue === null) {
265 |                         $currentDateEncrypt = $security->encrypt($currentDate, $decrypted_access_key);
266 |                         $tokenNameEncrypt = $security->encrypt($tokenName, $decrypted_access_key);
267 |                         $tokenName = $tokenNameEncrypt . '_' . $currentDateEncrypt;
268 |                         $response = [];
269 |                         $response['key'] = "User";
270 |                         $response['value'] = $tokenName;
271 |                         return $response;
272 |                     } else {
273 |                         $secretValue = explode('_', $secretValue);
274 |                         $decrypted_secret_key = $security->decrypt($secretValue[0], $decrypted_access_key);
275 |                         if ($decrypted_secret_key == $tokenName) {
276 |                             return YES;
277 |                         } else {
278 |                             return NO;
279 |                         }
280 |                     }
281 |                 } else {
282 |                     return NO;
283 |                 }
284 |             } else {
285 |                 return NO;
286 |             }
287 |         }
288 |         return NO;
289 |     }
290 | 
291 |     public function checkForSecurityForRefreshToken($accessValue, $secretValue)
292 |     {
293 |         $connection = $this->connection;
294 |         if ($accessValue == "") {
295 |             $data[STATUS_KEY] = FAILED;
296 |             $data[MESSAGE_KEY] = TOKEN_ERROR;
297 |         } else {
298 |             $objUserAgent = getSingleTableData($connection, TABLE_ADMIN_CONFIG, "", "config_value", "", ['config_key' => 'userAgent', 'is_delete' => DELETE_STATUS::NOT_DELETE]);
299 |             if (!empty($objUserAgent)) {
300 |                 $user_agent = $objUserAgent['config_value'];
301 |                 $separateKey = explode(',', $user_agent);
302 |                 if ((strpos($_SERVER ['HTTP_USER_AGENT'], $separateKey[0]) !== false) || (strpos($_SERVER ['HTTP_USER_AGENT'], $separateKey[1]) !== false) || (strpos($_SERVER ['HTTP_USER_AGENT'], $separateKey[2]) !== false) || (strpos($_SERVER ['HTTP_USER_AGENT'], $separateKey[3]) !== false) || (strpos($_SERVER ['HTTP_USER_AGENT'], $separateKey[4]) !== false) || (strpos($_SERVER ['HTTP_USER_AGENT'], $separateKey[5]) !== false) || (strpos($_SERVER ['HTTP_USER_AGENT'], $separateKey[6]) !== false)) {
303 |                     $getTempToken = getSingleTableData($connection, TABLE_ADMIN_CONFIG, "", "config_value", "", ['config_key' => 'tempToken', 'is_delete' => DELETE_STATUS::NOT_DELETE]);
304 |                     if (!empty($getTempToken)) {
305 |                         $tempToken = $getTempToken['config_value'];
306 |                         $objGlobalPassword = getSingleTableData($connection, TABLE_ADMIN_CONFIG, "", "config_value", "", ['config_key' => 'globalPassword', 'is_delete' => DELETE_STATUS::NOT_DELETE]);
307 |                         if (!empty($objGlobalPassword)) {
308 |                             $masterKey = $objGlobalPassword['config_value'];
309 |                             $security = new ApiCrypter();
310 |                             if ($accessValue === 'nousername') {
311 |                                 if ($secretValue == null) {
312 |                                     $secretValue = $security->encrypt($tempToken, $masterKey);
313 |                                     $response = [];
314 |                                     $response['key'] = "Temp";// return temporary token
315 |                                     $response['value'] = $secretValue;
316 |                                     return $response;
317 |                                 } else {
318 |                                     $secretValue = $security->decrypt($secretValue, $masterKey);
319 |                                     if ($secretValue == $tempToken) {
320 |                                         return YES;
321 |                                     }
322 |                                     return NO;
323 |                                 }
324 |                             } else {
325 |                                 $tempToken = $security->encrypt($tempToken, $masterKey);
326 |                                 return $this->checkCredentialsForSecurityNew($accessValue, $secretValue, $tempToken);
327 |                             }
328 |                         }
329 |                     }
330 |                 }
331 |             }
332 |         }
333 |         return NO;
334 |     }
335 | 
336 |     public function getAdminConfigWithToken($postData)
337 |     {
338 |         $data = [];
339 |         $connection = $this->connection;
340 | 
341 |         $secret_key = validateObject($postData, 'secret_key', "");
342 |         $secret_key = addslashes($secret_key);
343 | 
344 |         $access_key = validateObject($postData, 'access_key', "");
345 |         $access_key = addslashes($access_key);
346 | 
347 |         if ($access_key == "") {
348 |             $data[STATUS_KEY] = FAILED;
349 |             $data[MESSAGE_KEY] = TOKEN_ERROR;
350 |         } else {
351 |             $isSecure = $this->checkForSecurityNew($access_key, $secret_key);
352 |             if ($isSecure != NO) {
353 |                 $stmt_get_admin_config = getMultipleTableData($connection, TABLE_ADMIN_CONFIG, "", "config_key,config_value", " config_key IN('globalPassword','userAgent','tempToken')", ['is_delete' => DELETE_STATUS::NOT_DELETE]);
354 |                 if ($stmt_get_admin_config->rowCount() > 0) {
355 |                     while ($objAdminConfig = $stmt_get_admin_config->fetch(PDO::FETCH_ASSOC)) {
356 |                         $data[$objAdminConfig['config_key']] = $objAdminConfig['config_value'];
357 |                     }
358 |                 }
359 |                 $stmt_get_admin_config->closeCursor();
360 |             } else {
361 |                 $data = '';
362 |             }
363 |         }
364 |         return $data;
365 |     }
366 | 
367 |     private function generateToken($length)
368 |     {
369 |         $token = '';
370 |         $codeAlphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
371 |         $codeAlphabet .= 'abcdefghijklmnopqrstuvwxyz';
372 |         $codeAlphabet .= '0123456789';
373 |         $max = strlen($codeAlphabet) - 1;
374 |         for ($i = 0; $i < $length; $i++) {
375 |             $token .= $codeAlphabet[$this->crypto_random_secure(0, $max)];
376 |         }
377 |         return $token;
378 |     }
379 | 
380 |     private function refreshToken($userData)
381 |     {
382 |         $access_key = validateObject($userData, 'access_key', "");
383 |         $access_key = addslashes($access_key);
384 | 
385 |         $isSecure = $this->checkForSecurityForRefreshToken($access_key, "");
386 | 
387 |         if ($isSecure == NO) {
388 |             $status = FAILED;
389 |             $message = MALICIOUS_SOURCE;
390 |         } elseif ($isSecure == ERROR) {
391 |             $status = FAILED;
392 |             $message = TOKEN_ERROR;
393 |         } else {
394 |             //print_r($isSecure);
395 |             if ($isSecure != YES) {
396 |                 if ($isSecure['key'] === 'Temp') {
397 |                     $data['data']['tempToken'] = $isSecure['value'];
398 |                 } else {
399 |                     $data['data']['userToken'] = $isSecure['value'];
400 |                 }
401 |             }
402 |             $status = SUCCESS;
403 |             $message = 'Token is generated.';
404 |         }
405 | 
406 |         $data[STATUS_KEY] = $status;
407 |         $data[MESSAGE_KEY] = $message;
408 | 
409 |         $arr_adminconfig = $this->getAdminConfigWithToken($userData);
410 |         $arr_adminconfig['key_iv'] = $_ENV['ENCRYPTION_KEY_IV'];
411 |         $data['data']['adminConfig'] = $arr_adminconfig;
412 | 
413 |         return $data;
414 |     }
415 | 
416 |     private function testEncryption($userData)
417 |     {
418 |         $guid = validateValue($userData->guid, "");
419 |         $global_pwd_value = "_$(Skill)!_square@#$%_23_06_2017";
420 |         $security = new ApiCrypter();
421 |         $encrpt_acesskey = $security->encrypt($guid, $global_pwd_value);
422 |         $data['encrypted_value'] = $encrpt_acesskey;
423 |         $data['decrypted_value'] = $security->decrypt($encrpt_acesskey, $global_pwd_value);
424 |         return $data;
425 |     }
426 | 
427 |     private function expiredAllTokenOfUser($userData)
428 |     {
429 |         $user_id = validateValue($userData['userId'], '');
430 |         if ($user_id != '') {
431 |             $modifiedDate = date(DATETIME_FORMAT, time());
432 |             editData($this->connection, 'ExpireToken', TABLE_APP_TOKENS, ['modified_date' => $modifiedDate], ['userid' => $user_id], "");
433 |             return YES;
434 |         }
435 |         return NO;
436 |     }
437 | }
438 | 


--------------------------------------------------------------------------------
/src/TableVars.php:
--------------------------------------------------------------------------------
 1 | connection = $con;
 32 |     }
 33 | 
 34 |     public function callService($service, $postData)
 35 |     {
 36 |         switch ($service) {
 37 |             case self::LOGIN_ACTION:
 38 |                 return $this->login($postData);
 39 | 
 40 |             case self::LOGS_ACTION:
 41 |                 return $this->addLogs($postData);
 42 | 
 43 |             case self::REGISTRATION_ACTION:
 44 |                 return $this->registration($postData);
 45 | 
 46 |             case self::CHANGE_PASSWORD_ACTION:
 47 |                 return $this->changePassword($postData);
 48 | 
 49 |             case self::EDIT_PROFILE_ACTION:
 50 |                 return $this->editProfile($postData);
 51 | 
 52 |             case self::FORGOT_PASSWORD_ACTION:
 53 |                 return $this->forgotPassword($postData);
 54 | 
 55 |             case self::DELETE_ACCOUNT_ACTION:
 56 |                 return $this->deleteAccount($postData);
 57 | 
 58 |             case self::DATA_TAKEOUT:
 59 |                 return $this->dataTakeOut($postData);
 60 | 
 61 |             default:
 62 |                 return null;
 63 |         }
 64 |     }
 65 | 
 66 |     private function addLogs($userData)
 67 |     {
 68 | 
 69 |         $connection = $this->connection;
 70 | 
 71 |         $user_id = validateObject($userData, 'user_id', "");
 72 |         $user_id = addslashes($user_id);
 73 | 
 74 |         $api = validateObject($userData, 'api', "");
 75 |         $api = addslashes($api);
 76 | 
 77 |         $response = validateObject($userData, 'response', "");
 78 |         $response = addslashes($response);
 79 | 
 80 |         $user_array = [
 81 |             'api' => $api,
 82 |             'response' => $response,
 83 |             'user_id' => $user_id
 84 |         ];
 85 | 
 86 |         $user_response = addData($connection, 'Registration', TABLE_LOGS, $user_array);
 87 | 
 88 |         if ($user_response[STATUS_KEY] === SUCCESS) {
 89 |             $status = SUCCESS;
 90 |             $message = "successfully loged";
 91 |         } else {
 92 |             $status = FAILED;
 93 |             $message = SOMETHING_WENT_WRONG_TRY_AGAIN_LATER;
 94 |         }
 95 | 
 96 |         $data['status'] = $status;
 97 |         $data['message'] = $message;
 98 |         return $data;
 99 | 
100 |     }
101 | 
102 |     private function registration($userData)
103 |     {
104 |         $connection = $this->connection;
105 | 
106 |         $email_id = validateObject($userData, 'email_id', "");
107 |         $email_id = addslashes($email_id);
108 | 
109 |         $password = validateObject($userData, 'password', "");
110 |         $password = addslashes($password);
111 |         $password = encryptPassword($password);
112 | 
113 |         $first_name = validateObject($userData, 'first_name', "");
114 |         $first_name = addslashes($first_name);
115 | 
116 |         $last_name = validateObject($userData, 'last_name', "");
117 |         $last_name = addslashes($last_name);
118 | 
119 |         $device_type = validateObject($userData, 'device_type', "");
120 |         $device_type = addslashes($device_type);
121 | 
122 |         $device_token = validateObject($userData, 'device_token', "");
123 |         $device_token = addslashes($device_token);
124 | 
125 |         $posts = [];
126 |         $is_delete = IS_DELETE;
127 |         $created_date = date(self::DATETIME_FORMAT);
128 | 
129 |         $objUser = getSingleTableData(
130 |             $connection,
131 |             TABLE_USER,
132 |             '',
133 |             'id',
134 |             '',
135 |             [
136 |                 'email' => $email_id,
137 |                 'is_delete' => $is_delete]
138 |         );
139 |         if (!empty($objUser)) {
140 |             $status = FAILED;
141 |             $message = EMAIL_ALREADY_EXISTS;
142 |         } else {
143 |             //INSERT USER
144 |             $security = new Security($connection);
145 |             $generate_guid = $security->generateUniqueId();
146 |             $user_array = [
147 |                 'email' => $email_id,
148 |                 'first_name' => $first_name,
149 |                 'last_name' => $last_name,
150 |                 'password' => $password,
151 |                 'device_type' => $device_type,
152 |                 'device_token' => $device_token,
153 |                 'created_date' => $created_date,
154 |                 'guid' => $generate_guid
155 |             ];
156 |             $user_response = addData($connection, 'Registration', TABLE_USER, $user_array);
157 |             if ($user_response[STATUS_KEY] === SUCCESS) {
158 |                 $user_inserted_id = $user_response[MESSAGE_KEY];
159 |                 $getUser = getSingleTableData(
160 |                     $connection,
161 |                     TABLE_USER,
162 |                     '',
163 |                     '*',
164 |                     '',
165 |                     [
166 |                         'id' => $user_inserted_id,
167 |                         'is_delete' => $is_delete
168 |                     ]
169 |                 );
170 |                 if (!empty($getUser)) {
171 |                     $tokenData = new stdClass;
172 |                     $tokenData->GUID = $getUser['guid'];
173 |                     $tokenData->userId = $getUser['id'];
174 |                     $user_token = $security->updateTokenForUserLogin($tokenData);
175 |                     if ($user_token[STATUS_KEY] === SUCCESS) {
176 |                         $data[USERTOKEN] = $user_token[USERTOKEN];
177 |                     }
178 |                     $posts[] = $getUser;
179 |                     $status = SUCCESS;
180 |                     $message = REGISTRATION_SUCCESSFULLY_DONE;
181 |                     try {
182 |                         $this->sendWelcomeEmail(
183 |                             [
184 |                                 'first_name' => $first_name,
185 |                                 'email_id' => $email_id,
186 |                                 'subject' => 'Welcome on Lifyzer Community 😊'
187 |                             ],
188 |                             new Email()
189 |                         );
190 |                     } catch (Exception $e) {
191 |                         $status = FAILED;
192 |                         $message = SOMETHING_WENT_WRONG_TRY_AGAIN_LATER;
193 |                     }
194 |                 } else {
195 |                     $status = FAILED;
196 |                     $message = DEFAULT_NO_RECORD;
197 |                 }
198 |             } else {
199 |                 $status = FAILED;
200 |                 $message = SOMETHING_WENT_WRONG_TRY_AGAIN_LATER;
201 |             }
202 |         }
203 |         $data['status'] = $status;
204 |         $data['message'] = $message;
205 |         $data['User'] = $posts;
206 |         return $data;
207 |     }
208 | 
209 |     private function editProfile($userData)
210 |     {
211 |         $connection = $this->connection;
212 | 
213 |         $user_id = validateObject($userData, 'user_id', "");
214 |         $user_id = addslashes($user_id);
215 | 
216 |         $email_id = validateObject($userData, 'email_id', "");
217 |         $email_id = addslashes($email_id);
218 | 
219 |         $first_name = validateObject($userData, 'first_name', "");
220 |         $first_name = utf8_decode($first_name);
221 | 
222 |         $is_delete = IS_DELETE;
223 |         $posts = [];
224 | 
225 |         $objUserEmail = getSingleTableData(
226 |             $connection,
227 |             TABLE_USER,
228 |             '', '*',
229 |             " id != $user_id ",
230 |             [
231 |                 'email' => $email_id,
232 |                 'is_delete' => $is_delete
233 |             ]
234 |         );
235 |         if (!empty($objUserEmail)) {
236 |             $created_date = getDefaultDate();
237 |             $update_array = ['first_name' => $first_name, 'email' => $email_id, 'modified_date' => $created_date];
238 |             $edit_response = editData($connection, 'UpdateProfile', TABLE_USER, $update_array, ['id' => $user_id]);
239 |             if ($edit_response[STATUS_KEY] === SUCCESS) {
240 |                 $getUser = getSingleTableData($connection, TABLE_USER, "", "*", "", ['id' => $user_id, 'is_delete' => $is_delete]);
241 |                 if (!empty($getUser)) {
242 |                     $posts[] = $getUser;
243 |                 }
244 |                 $status = SUCCESS;
245 |                 $message = PROFILE_UPDATED_SUCCESSFULLY;
246 |             } else {
247 |                 $status = FAILED;
248 |                 $message = SOMETHING_WENT_WRONG_TRY_AGAIN_LATER;
249 |             }
250 |         } else {
251 |             $status = FAILED;
252 |             $message = EMAIL_ALREADY_EXISTS;
253 |         }
254 |         $data['status'] = $status;
255 |         $data['message'] = $message;
256 |         $data['User'] = $posts;
257 |         return $data;
258 |     }
259 | 
260 |     private function changePassword($userData)
261 |     {
262 |         $connection = $this->connection;
263 | 
264 |         $user_id = validateObject($userData, 'user_id', "");
265 |         $user_id = addslashes($user_id);
266 | 
267 |         $password = validateObject($userData, 'password', "");
268 |         $password = addslashes($password);
269 |         $password = encryptPassword($password);
270 | 
271 |         $new_password = validateObject($userData, 'new_password', "");
272 |         $new_password = addslashes($new_password);
273 |         $new_password = encryptPassword($new_password);
274 | 
275 |         $is_delete = IS_DELETE;
276 |         $posts = [];
277 | 
278 |         $objUser = getSingleTableData($connection, TABLE_USER, "", "id,password", "", ['id' => $user_id, 'is_delete' => $is_delete]);
279 |         if (!empty($objUser)) {
280 |             if (hash_equals($objUser['password'], $password)) {
281 |                 $created_date = getDefaultDate();
282 |                 $edit_response = editData($connection, "Login", TABLE_USER, ['password' => $new_password, 'modified_date' => $created_date], ['id' => $user_id]);
283 |                 if ($edit_response[STATUS_KEY] === SUCCESS) {
284 |                     $getUser = getSingleTableData($connection, TABLE_USER, "", "*", "", ['id' => $user_id, 'is_delete' => $is_delete]);
285 |                     if (!empty($getUser)) {
286 |                         $posts[] = $getUser;
287 |                         $status = SUCCESS;
288 |                         $message = PASSWORD_CHANGED;
289 |                     } else {
290 |                         $status = FAILED;
291 |                         $message = DEFAULT_NO_RECORD;
292 |                     }
293 |                 } else {
294 |                     $status = FAILED;
295 |                     $message = SOMETHING_WENT_WRONG_TRY_AGAIN_LATER;
296 |                 }
297 |             } else {
298 |                 $status = FAILED;
299 |                 $message = CHNG_WRONG_PASSWORD_MESSAGE;
300 |             }
301 |         } else {
302 |             $status = FAILED;
303 |             $message = NO_DATA_AVAILABLE;
304 |         }
305 |         $data['status'] = $status;
306 |         $data['message'] = $message;
307 |         $data['User'] = $posts;
308 |         return $data;
309 |     }
310 | 
311 |     private function login($userData)
312 |     {
313 |         $connection = $this->connection;
314 | 
315 |         $email_id = validateObject($userData, 'email_id', "");
316 |         $email_id = addslashes($email_id);
317 | 
318 |         $password = validateObject($userData, 'password', "");
319 |         $password = addslashes($password);
320 |         $password = encryptPassword($password);
321 | 
322 |         $device_type = validateObject($userData, 'device_type', "");
323 |         $device_type = addslashes($device_type);
324 | 
325 |         $posts = [];
326 |         $is_delete = IS_DELETE;
327 |         $token = '';
328 | 
329 |         $objUser = getSingleTableData($connection, TABLE_USER, '', "*", "", ['email' => $email_id, 'is_delete' => $is_delete]);
330 |         if (!empty($objUser)) {
331 |             if (hash_equals($objUser['password'], $password)) {
332 |                 $user_id = $objUser['id'];
333 |                 $created_date = getDefaultDate();
334 |                 $edit_response = editData($connection, "Login", TABLE_USER, ['device_type' => $device_type, 'modified_date' => $created_date], ['id' => $user_id]);
335 |                 if ($edit_response[STATUS_KEY] === SUCCESS) {
336 |                     if ($objUser['guid'] == null || $objUser['guid'] == '') {
337 |                         $generate_user_guid = $this->updateGuidForUser($user_id);
338 |                     } else {
339 |                         $generate_user_guid = $objUser['guid'];
340 |                     }
341 |                     $tokenData = new stdClass;
342 |                     $tokenData->GUID = $generate_user_guid;
343 |                     $tokenData->userId = $user_id;
344 |                     $security = new Security($connection);
345 |                     $user_token = $security->updateTokenForUserLogin($tokenData);
346 |                     if ($user_token[STATUS_KEY] === SUCCESS) {
347 |                         $token = $user_token[USERTOKEN];
348 |                     }
349 |                     $objUser['device_type'] = $device_type;
350 |                     $objUser['modified_date'] = $created_date;
351 |                     $posts[] = $objUser;
352 |                     $status = SUCCESS;
353 |                     $message = USER_LOGIN_SUCCESSFULLY;
354 |                     $data[USERTOKEN] = $token;
355 |                 } else {
356 |                     $status = FAILED;
357 |                     $message = SOMETHING_WENT_WRONG_TRY_AGAIN_LATER;
358 |                 }
359 |             } else {
360 |                 $status = FAILED;
361 |                 $message = WRONG_PASSWORD_MESSAGE;
362 |             }
363 |         } else {
364 |             $status = FAILED;
365 |             $message = NO_EMAIL_AND_PASSWORD_AVAILABLE;
366 |         }
367 |         $data['status'] = $status;
368 |         $data['message'] = $message;
369 |         $data['User'] = $posts;
370 |         return $data;
371 |     }
372 | 
373 |     private function updateGuidForUser($user_id)
374 |     {
375 |         $connection = $this->connection;
376 |         $is_delete = DELETE_STATUS::NOT_DELETE;
377 |         $objUser = getSingleTableData($connection, TABLE_USER, "", "id,guid", "", ['id' => $user_id, 'is_delete' => $is_delete]);
378 |         if (!empty($objUser)) {
379 |             $security = new Security($connection);
380 |             $generate_guid = $security->generateUniqueId();
381 |             $edit_response = editData($connection, 'updateGuidForUser', TABLE_USER, ['guid' => $generate_guid], ['id' => $user_id]);
382 |             if ($edit_response[STATUS_KEY] === SUCCESS) {
383 |                 return $generate_guid;
384 |             }
385 |         }
386 | 
387 |         return '';
388 |     }
389 | 
390 |     private function forgotPassword($userData)
391 |     {
392 |         $connection = $this->connection;
393 |         $is_delete = IS_DELETE;
394 | 
395 |         $email_id = validateObject($userData, 'email_id', '');
396 |         $email_id = addslashes($email_id);
397 | 
398 |         $objUser = getSingleTableData(
399 |             $connection,
400 |             TABLE_USER,
401 |             '',
402 |             'id,first_name',
403 |             '',
404 |             [
405 |                 'email' => $email_id,
406 |                 'is_delete' => $is_delete
407 |             ]
408 |         );
409 | 
410 |         if (!empty($objUser)) {
411 |             $userPassword = generateRandomString(self::FORGOT_PASSWORD_LENGTH);
412 |             $dbPassword = encryptPassword($userPassword);
413 |             $created_date = getDefaultDate();
414 |             $edit_response = editData(
415 |                 $connection,
416 |                 'Forgot Password',
417 |                 TABLE_USER,
418 |                 [
419 |                     'password' => $dbPassword,
420 |                     'modified_date' => $created_date
421 |                 ],
422 |                 [
423 |                     'email' => $email_id
424 |                 ]
425 |             );
426 | 
427 |             if ($edit_response[STATUS_KEY] === SUCCESS) {
428 |                 try {
429 |                     $this->sendForgotPassword(
430 |                         [
431 |                             'first_name' => $objUser['first_name'],
432 |                             'email_id' => $email_id,
433 |                             'subject' => 'Forgot Password',
434 |                             'password' => $userPassword
435 |                         ],
436 |                         new Email()
437 |                     );
438 |                     $status = SUCCESS;
439 |                     $message = PASSWORD_SENT;
440 |                 } catch (Exception $e) {
441 |                     $status = FAILED;
442 |                     $message = SOMETHING_WENT_WRONG_TRY_AGAIN_LATER;
443 |                 }
444 |             } else {
445 |                 $status = FAILED;
446 |                 $message = SOMETHING_WENT_WRONG_TRY_AGAIN_LATER;
447 |             }
448 |         } else {
449 |             $status = FAILED;
450 |             $message = NO_DATA_AVAILABLE;
451 |         }
452 |         $data['status'] = $status;
453 |         $data['message'] = $message;
454 | 
455 |         return $data;
456 |     }
457 | 
458 |     /**
459 |      * @param array $data
460 |      * @param Email $email
461 |      *
462 |      * @throws Exception
463 |      */
464 |     private function sendWelcomeEmail(array $data, Email $email)
465 |     {
466 |         $sCookbookPdfUrl = static::COOKBOOK_PDF_URL;
467 |         $sCookbookEpubUrl = static::COOKBOOK_EPUB_URL;
468 | 
469 |         $htmlMessage =
470 |             <<
472 |         

Hi {$data['first_name']},

473 |

I'm Pierre-Henry Soria, the CEO of Lifyzer, Healthy Food Solution™️

474 |

So glad to see you on the platform. I really hope you will enjoy your experience!

475 |

You can even rate and comment your favorite products, and share your opinion with your friends! 🤗

476 |

🏆 Finally, if you enjoy the experience, leave your feedback on the App Store, and I will do my best to send you a little surprise, just for YOU! ❤️

477 |

Psst, Here is by gift to you! (ePub format here) 🧧 A vegetarian cookbook (worths $5.99 on Amazon). Hopefully, you will appreciate it! 😊

478 |

 

479 |

Best, 💚
480 | Pierre-Henry Soria

481 | 482 | HTML; 483 | 484 | $email->sendMail( 485 | $htmlMessage, 486 | $data['subject'], 487 | $data['email_id'] 488 | ); 489 | } 490 | 491 | /** 492 | * @param array $data 493 | * @param Email $email 494 | * 495 | * @throws Exception 496 | */ 497 | private function sendForgotPassword(array $data, Email $email) 498 | { 499 | $htmlMessage = 500 | << 502 |

Hi {$data['first_name']},

503 |

Your new password for Lifyzer App is:
{$data['password']}

504 |

 

505 |

Best,
Lifyzer, Healthy Food 🍍

506 | 507 | HTML; 508 | $email->sendMail( 509 | $htmlMessage, 510 | $data['subject'], 511 | $data['email_id'] 512 | ); 513 | } 514 | 515 | private function deleteAccount(array $userData): array 516 | { 517 | $email_id = validateObject($userData, 'email_id', ''); 518 | $sqlQuery = 'DELETE FROM %s WHERE email = :emailId LIMIT 1'; 519 | $stmt = $this->connection->prepare( 520 | sprintf($sqlQuery, TABLE_USER) 521 | ); 522 | $stmt->bindValue(':emailId', $email_id); 523 | if ($stmt->execute()) { 524 | $status = SUCCESS; 525 | $message = 'Account successfully deleted'; 526 | } else { 527 | $status = FAILED; 528 | $message = SOMETHING_WENT_WRONG_TRY_AGAIN_LATER; 529 | } 530 | $data['status'] = $status; 531 | $data['message'] = $message; 532 | return $data; 533 | } 534 | 535 | /** 536 | * Data takeout feature. Ideal to be GDPR compliant. 537 | * 538 | * @param array $userData 539 | * 540 | * @return array 541 | */ 542 | private function dataTakeOut(array $userData): array 543 | { 544 | $email_id = validateObject($userData, 'email_id', ''); 545 | 546 | $sqlQuery = <<connection->prepare( 554 | sprintf( 555 | $sqlQuery, 556 | TABLE_USER, 557 | TABLE_HISTORY, 558 | TABLE_FAVOURITE 559 | ) 560 | ); 561 | $stmt->bindValue(':emailId', $email_id); 562 | $stmt->execute(); 563 | $data = []; 564 | $dbData = $stmt->fetch(PDO::FETCH_ASSOC); 565 | $data['data'] = $this->buildCsvDataFormat($dbData); 566 | 567 | if (!empty($data)) { 568 | $status = SUCCESS; 569 | $message = 'You full data have been exported!'; 570 | } else { 571 | $status = FAILED; 572 | $message = NO_DATA_AVAILABLE; 573 | } 574 | $data['status'] = $status; 575 | $data['message'] = $message; 576 | return $data; 577 | } 578 | 579 | private function buildCsvDataFormat(array $data): string 580 | { 581 | $csvData = self::CSV_TAKEOUT_HEADER; 582 | $csvData .= implode(',', $data); 583 | return $csvData; 584 | } 585 | } 586 | --------------------------------------------------------------------------------