File: /home/assibfaf/public_html/prox-controllers/Api/Profile.php
<?php
/**
* @package Proxim
* @author Davison Pro <davisonpro.coder@gmail.com | https://davisonpro.dev>
* @copyright 2019 Proxim
* @version 1.0.0
* @since File available since Release 1.0.0
*/
namespace Proxim\Api;
use Db;
use Proxim\Database\DbQuery;
use Proxim\Route;
use Proxim\Coupon;
use Proxim\Site\Site;
use Proxim\Order\Order;
use Proxim\User\Customer;
use Proxim\User\Wallet as CustomerWallet;
use Proxim\User\Employee;
use Proxim\Configuration;
use Proxim\Currency;
use Proxim\Validate;
use Proxim\Tools;
use Proxim\Util\ArrayUtils;
use Proxim\Util\DateUtils;
use Proxim\Crypto\Hashing;
use Proxim\Hook;
use Proxim\Module\Module;
use Proxim\Presenter\Profile\ProfilePresenter;
class Profile extends Route {
public function register() {
$app = $this->app;
$request = $app->request();
$payload = $request->post();
$user = $app->container->user;
$email = ArrayUtils::get($payload, 'email');
$fname = ArrayUtils::get($payload, 'fname');
$phone = ArrayUtils::get($payload, 'phone');
$mobilePhoneCountryHidden = ArrayUtils::get($payload, 'mobilePhoneCountryHidden');
$password = ArrayUtils::get($payload, 'password');
$confirmPassword = ArrayUtils::get($payload, 'confirmPassword');
$agreePrivacyPolicy = ArrayUtils::get($payload, 'agreePrivacyPolicy');
$agreeSubscription = ArrayUtils::get($payload, 'agreeSubscription');
$agreeTermsAndConditions = ArrayUtils::get($payload, 'agreeTermsAndConditions');
/** Email Validation */
if ( !$email ) {
return $app->response([
'success' => false,
'errors' => [
'email' => 'Email is required'
]
]);
}
if(!validate::isEmail($email)) {
return $app->response([
'success' => false,
'errors' => [
'email' => 'Enter a valid Email address'
]
]);
}
$customer = $user->getByEmail($email);
if ( Validate::isLoadedObject($customer) ) {
return $app->response([
'success' => false,
'errors' => [
'email' => 'E-mail already registered.'
]
]);
}
/** Name Validation */
if(Configuration::get('AUTH_REQUIRE_NAME', PROX_SITE_ID, true) && !Validate::isName($fname)) {
return $app->response([
'success' => false,
'errors' => [
'fname' => 'Enter a valid name'
]
]);
}
/** Phone Validation */
if(Configuration::get('AUTH_REQUIRE_PHONE', PROX_SITE_ID, true) && !$phone) {
return $app->response([
'success' => false,
'errors' => [
'fname' => 'Enter a valid phone number'
]
]);
}
/** Password Validation */
if ( !$password || !Validate::isPasswd($password)) {
return $app->response([
'success' => false,
'errors' => [
'password' => 'Password is required'
]
]);
}
if ( !$confirmPassword || !Validate::isPasswd($confirmPassword)) {
return $app->response([
'success' => false,
'errors' => [
'confirmPassword' => 'Confirm Password is required'
]
]);
}
if ( $confirmPassword !== $password ) {
return $app->response([
'success' => false,
'errors' => [
'confirmPassword' => 'Your passwords do not match'
]
]);
}
/** Privacy and Terms */
if( !$agreeTermsAndConditions ) {
return $app->response([
'success' => false,
'errors' => [
'agreeTermsAndConditions' => 'You must agree to the Terms and Conditions before registering'
]
]);
}
if( !$agreePrivacyPolicy ) {
return $app->response([
'success' => false,
'errors' => [
'agreePrivacyPolicy' => 'You must agree to the Privacy Policy before registering'
]
]);
}
$crypto = new Hashing();
$customer = new Customer();
$customer->google_analytics_id = Tools::randomGen(32);
$customer->email = $email;
$customer->name = $fname ? $fname : '';
$customer->phone = $phone ? $phone : '';
$customer->country_id = (int) $mobilePhoneCountryHidden;
$customer->password = $crypto->hash(
$password,
PROX_COOKIE_KEY
);
$customer->is_subscribed = (bool) $agreeSubscription;
$customer->policy_accepted = 1;
$customer->policy_accepted_at = DateUtils::now();
$customer->reg_date = DateUtils::now();
if ( $app->container->cookie->referrer_id ) {
$referrer = new Customer( (int) $app->container->cookie->referrer_id );
if (Validate::isLoadedObject($referrer)) {
$customer->referrer_id = $referrer->id;
}
}
$ok = $customer->add(true, true);
if ( !$ok ) {
return $app->response([
"success" => false,
"errors" => [
"Sorry, there was a problem creating your account"
]
]);
}
Hook::exec('actionCustomerAccountAdd', ['newCustomer' => $customer]);
$site = new Site( (int) $customer->site_id );
if( Validate::isLoadedObject($site) ) {
$site->customers = $site->customers+1;
$site->update();
}
// update user
$app->updateUser( $customer );
return $app->response([
"success" => true,
"user_id" => $customer->id
]);
}
public function validateEmail() {
$app = $this->app;
$request = $app->request();
$payload = $request->post();
$user = $app->container->user;
$email = ArrayUtils::get($payload, 'email');
if ( !$email || !Validate::isEmail($email) ) {
return $app->response([
"success" => false,
"errors" => [
'email' => 'Email is required'
]
]);
}
$customer = $user->getByEmail($email);
if ( Validate::isLoadedObject($customer) ) {
return $app->response([
"success" => true,
"data" => [
"existing_client" => true,
"user_id" => $customer->id
]
]);
}
return $app->response([
"success" => true,
"data" => [
"existing_client" => false,
]
]);
}
public function isSurveyComplete() {
$app = $this->app;
$request = $app->request();
$payload = $request->get();
$user = $app->container->user;
return $app->response([
"success" => true,
"isSurveyComplete" => false
]);
}
public function getProfile() {
global $globals;
$app = $this->app;
$payload = $app->request->get();
$user = $app->container->user;
$countries = ArrayUtils::get($globals, 'countries');
$country_id = array_search($user->country_id, array_column($countries, 'code'));
$country_code = ArrayUtils::get(array_keys($countries), $country_id);
$country = ArrayUtils::has($countries, $country_code) ? ArrayUtils::get($countries, $country_code) : array();
$profilePresenter = new ProfilePresenter();
$profile = $profilePresenter->present($user);
return $app->response([
"success" => true,
"profile" => $profile
]);
}
public function getDiscounts() {
$app = $this->app;
$user = $app->container->user;
$coupons = $customer_coupons = array();
$coupons_enabled = (bool) Configuration::get('DISCOUNTS_ENABLED');
/** Lifetime discounts **/
$discount_percent = 0;
if ( $coupons_enabled && $user->total_spent >= 500 ) {
if ( $user->total_spent >= 2000 ) {
$discount_percent = 15;
} elseif ( $user->total_spent >= 1000 ) {
$discount_percent = 10;
} else {
$discount_percent = 5;
}
$coupons[] = array(
"coupon_id" => (int) $user->id,
"coupon_type" => (int) Coupon::PERCENT,
"coupon_code" => $discount_percent."% OFF",
"value" => (int) $discount_percent,
"order_id" => null,
"lifetime" => true,
"expired_at" => null,
);
}
/** Available active coupons */
$active_coupons = Coupon::getCoupons( true, true );
foreach ($active_coupons as $coupon) {
$coupon_type = ArrayUtils::get($coupon, 'coupon_type');
$user_id = ArrayUtils::get($coupon, 'user_id');
if ( $user_id && $user_id != $user->id ) {
continue;
}
$order_id = ArrayUtils::get($coupon, 'order_id');
if ( $order_id ) {
$order = new Order( (int) $order_id );
if (!Validate::isLoadedObject($order)) continue;
if ($order->customer_id != $user->id) continue;
}
if( $coupon_type == Coupon::FREE_UNIT ) {
$customer_coupons[] = array(
"id" => (int) $coupon['coupon_id'],
"service_type_id" => (int) $coupon['service_type_id'],
"type_id" => (int) $coupon['coupon_type'],
"order_id" => (int) $coupon['order_id'],
);
} else {
$coupons[] = array(
"coupon_id" => (int) $coupon['coupon_id'],
"coupon_type" => (int) $coupon['coupon_type'],
"coupon_code" => $coupon['coupon_code'],
"value" => (int) $coupon['coupon_value'],
"order_id" => (int) $coupon['order_id'],
"lifetime" => false,
"expired_at" => DateUtils::hasPassed( $coupon['expiry'] ) ? $coupon['expiry'] : null,
);
}
}
return $app->response([
"success" => true,
"user_coupons" => [
"user_id" => $user->id,
"totalSpent" => (float) $user->total_spent,
"discountPercent" => (int) $discount_percent,
"coupons" => $coupons,
"customerCoupons" => $customer_coupons
]
]);
}
public function couponExists( $couponCode ) {
$app = $this->app;
$user = $app->container->user;
if(!$couponCode) {
return $app->response([
"success" => false,
"errors" => null
]);
}
$coupon_id = Coupon::getIdByCouponCode( pSql($couponCode) );
if(!$coupon_id) {
return $app->response([
"success" => false,
"errors" => [
"This coupon code is invalid or has expired"
]
]);
}
$coupon = new Coupon( (int) $coupon_id );
if(!Validate::isLoadedObject($coupon)) {
return $app->response([
"success" => false,
"errors" => [
"This coupon code is invalid or has expired"
]
]);
}
if ( $coupon->site_id != Configuration::get('SITE_ID', $user->site_id) ) {
return $app->response([
"success" => false,
"errors" => [
"This coupon code is invalid or has expired"
]
]);
}
// check expiry
if( !$coupon->active && DateUtils::hasPassed( $coupon->expiry ) ) {
return $app->response([
"success" => false,
"errors" => [
"This coupon code is invalid or has expired"
]
]);
}
// validate user ID
if ( $coupon->user_id && $coupon->user_id != $user->id ) {
return $app->response([
"success" => false,
"errors" => [
"This coupon code is invalid or has expired"
]
]);
}
// validate order ID
if ( $coupon->order_id ) {
$order = new Order( (int) $coupon->order_id );
if ( !Validate::isLoadedObject($order) ) {
return $app->response([
"success" => false,
"errors" => [
"This coupon code is invalid or has expired"
]
]);
}
if ($order->customer_id != $user->id) {
return $app->response([
"success" => false,
"errors" => [
"This coupon code is invalid or has expired"
]
]);
}
}
return $app->response([
"success" => true,
"coupon" => array(
"coupon_id" => (int) $coupon->id,
"coupon_type" => (int) $coupon->coupon_type,
"coupon_code" => $coupon->coupon_code,
"value" => (float) $coupon->coupon_value,
"order_id" => (int) $coupon->order_id,
"lifetime" => false,
"expired_at" => DateUtils::hasPassed( $coupon->expiry ) ? $coupon->expiry : null,
)
]);
}
public function getWriters() {
$app = $this->app;
$request = $app->request();
$payload = $request->get();
$user = $app->container->user;
$sql = new DbQuery();
$sql->select('DISTINCT o.writer_id');
$sql->from('order', 'o');
$sql->where('o.`customer_id` = '. (int) $user->id);
$sql->where('o.`status_id` = '. Order::FINISHED );
$result = Db::getInstance()->executeS($sql);
$writers = array();
foreach ( $result as $writer ) {
$writer = new Employee( (int) $writer['writer_id'] );
if (Validate::isLoadedObject($writer)) {
$sql = new DbQuery();
$sql->select('o.order_id');
$sql->from('order', 'o');
$sql->where('o.`customer_id` = '. (int) $user->id);
$sql->where('o.`writer_id` = '. (int) $writer->id);
$sql->where('o.`status_id` = '. Order::FINISHED );
$orderId = Db::getInstance()->getValue($sql);
$writers[] = array(
"id" => (int) $writer->id,
"content" => "$writer->first_name - $writer->id (completed your order $orderId)",
"category" => (int) $writer->writer_category,
"percent" => (int) $writer->writer_percent,
"value" => (int) $writer->writer_percent
);
}
}
return $app->response([
"success" => true,
"writers" => $writers
]);
}
public function updateContacts() {
$app = $this->app;
$payload = $app->request->post();
$user = $app->container->user;
$name = ArrayUtils::get($payload, 'name');
if ( !$name || !Validate::isName($name)) {
return $app->response([
"success" => false,
"errors" => [
"Your name contains invalid characters"
]
]);
}
if ( Tools::strlen($name) > 20 ) {
return $app->response([
"success" => false,
"errors" => [
"Your name must be less than 20 characters long. Please try another"
]
]);
}
if ( Tools::strlen($name) < 3 ) {
return $app->response([
"success" => false,
"errors" => [
"Your name must be at least 3 characters long. Please try another"
]
]);
}
$phone = (int) ArrayUtils::get($payload, 'phone');
$user->name = $name;
$user->phone = $phone;
$ok = $user->update();
return $app->response([
"success" => true,
"errors" => null
]);
}
public function updatePassword() {
$app = $this->app;
$payload = $app->request->post();
$user = $app->container->user;
$oldPassword = ArrayUtils::get($payload, 'oldPassword');
$newPassword = ArrayUtils::get($payload, 'newPassword');
$confirmPassword = ArrayUtils::get($payload, 'confirmPassword');
if (!$oldPassword && !$newPassword) {
return $app->response([
"success" => false,
"errors" => [
"You must fill in all of the fields"
]
]);
}
/* validate new password */
if($newPassword != $confirmPassword) {
return $app->response([
"success" => false,
"errors" => [
"Your passwords do not match"
]
]);
}
if( !Validate::isPasswd($newPassword) ) {
return $app->response([
"success" => false,
"errors" => [
"Password must be at least 6 characters long. Please try another"
]
]);
}
$crypto = new Hashing();
$customer = $user->getByEmail(
$user->email,
$oldPassword
);
if (!Validate::isLoadedObject($customer)) {
return $app->response([
"success" => false,
"errors" => [
"Invalid current password"
]
]);
}
$user->password = $crypto->hash(
$newPassword,
PROX_COOKIE_KEY
);
$user->update();
return $app->response([
"success" => true,
"errors" => null
]);
}
public function subscribe() {
$app = $this->app;
$payload = $app->request->post();
$user = $app->container->user;
$isSubscribed = (bool) ArrayUtils::get($payload, 'isSubscribed');
$user->policy_accepted = 1;
$user->policy_accepted_at = DateUtils::now();
$user->is_subscribed = $isSubscribed;
$ok = $user->update();
return $app->response([
"success" => true,
]);
}
public function pushNotificationsEnabled() {
$app = $this->app;
$payload = $app->request->post();
$user = $app->container->user;
return $app->response([
"success" => true,
]);
}
public function policyConfirmation() {
$app = $this->app;
$request = $app->request();
$payload = $request->post();
$user = $app->container->user;
$user->policy_accepted = 1;
$user->policy_accepted_at = DateUtils::now();
$user->update();
return $app->response([
"success" => true,
]);
}
public function getWallet() {
$app = $this->app;
$payload = $app->request->post();
$user = $app->container->user;
if(!Configuration::get('WALLET_ENABLED', PROX_ADMIN_SITE_ID)) {
return $app->response([
"success" => true,
"wallet" => array(
"wallet_balance" => (float) toFixed(0),
"wallet_transactions" => array()
)
]);
}
$walletId = CustomerWallet::getIdByCustomerId( $user->id );
$wallet = new CustomerWallet( (int) $walletId );
if(!Validate::isLoadedObject($wallet)) {
return $app->response([
"success" => true,
"wallet" => array(
"wallet_balance" => (float) toFixed(0),
"wallet_transactions" => array()
)
]);
}
$sql = new DbQuery();
$sql->from('wallet_transaction');
$sql->where('wallet_id = ' . (int) $wallet->id );
$sql->orderBy('wallet_transaction_id DESC');
$sql->limit(10);
$result = Db::getInstance()->executeS($sql);
$transactions = array();
foreach($result as $transaction) {
$transactions[] = array(
'id' => (int) $transaction['wallet_transaction_id'],
'source' => (string) $transaction['source'],
'amount' => (float) $transaction['amount'],
'date' => DateUtils::convertToISOFormat($transaction['date_add'])
);
}
return $app->response([
"success" => true,
"wallet" => array(
"wallet_balance" => (float) $wallet->wallet_balance,
"wallet_transactions" => $transactions
)
]);
}
public function loadWallet() {
$app = $this->app;
$payload = $app->request->post();
$user = $app->container->user;
$amount = ArrayUtils::get($payload, 'amount');
$paymentMethod = ArrayUtils::get($payload, 'paymentMethod');
if(!Validate::isPrice($amount)) {
return $app->response([
"success" => false,
"errors" => [
"Enter a valid amount"
]
]);
}
$paymentModule = Module::getInstanceByName($paymentMethod);
if(!Validate::isLoadedObject($paymentModule)) {
return $app->response([
"success" => false,
"errors" => "Select a valid payment method"
]);
}
$redirect = Configuration::get('SITE_DOMAIN') . '/checkout/' . $paymentMethod . '/wallet/' . $amount;
return $app->response([
"success" => true,
"redirect_to" => $redirect
]);
}
}