Sixtens hemsida Uppgifter Blogg Om

Bankapplikation

Gå till sida

Källkod

bank/

logout.php

transfer.php

index.php

login.php

manage.php

signup.php

change_password.php

modules/

user.php

page.php

session.php

utility.php

users/

hjk.json

sixten2.json

sixten.json

wesweb01/bank/modules/user.php

1 lines
<?php
# Fil som skapar klass för användare och användardata.

require "utility.php";
date_default_timezone_set('Europe/Stockholm'); # Används för när transaktioner sparas.
# Datum skrivs ner och man vill ha det i rätt tidszon.
class User
    
# En klass för en användare. Innehåller funktioner för transaktioner och datalagring.
{
    public static 
$storage "users/%s.json"# Sökväg till sparade användare.
    # %s ersätts med namnet till användaren med hjälp av sprintf.

    
public $username;
    public 
$password;
    public 
$salt# Salt för lösenordet, för ökad säkerhet.
    
public $accounts# Lista med kontoobjekt.
    
public static function LoadUser($username): ?User
    
# Statisk funktion som försöker ladda en användare från användarnamn.
    # Hämtar ett användarobjekt.
    
{
        
$file sprintf(self::$storagestrtolower($username)); # Här används sprintf för att få filen till användaren. 
        
if (!file_exists(($file))) # Kollar ifall användaren saknas.
            
return null;
        
$jsonData json_decode(file_get_contents($file)); # Laddar datan från filen.

        
$user = new User(); # Skapar ett blankt användarobjekt
        # Sedan överförs data från jsonData till user.
        # Anledningen att jag gör det en för en är för att jag vill ha kontroll över vilka klasser som den lästa datan har.
        # Exempelvis vill jag att accounts ska vara en lista på kontoobjekt.
        # Det hade varit smidigt att definiera en struktur och ladda json-data utifrån den, som man kan i exempelvis C#
        # men vad jag vet så går inte det i php.
        
$user->username $jsonData->username;
        
$user->password $jsonData->password;
        
$user->salt $jsonData->salt;
        
$user->accounts = array();
        foreach (
$jsonData->accounts as $account) { # Här skapar vi kontoobjekt för varje konto.
            
array_push($user->accounts, new Account($account->name$account->transactions$account->mainAccount$account->id$account->active));
        }

        return 
$user;
    }

    public static function 
RegisterUser($username$password): ?User
    
# Statisk funktion som skapar ett konto från användarnamn och lösenord.
    
{
        if (
self::UserExists($username)) # Kollar ifall användarnamnet redan är taget.
            
return null;

        
$salt generate_uuid(); # Skapar lösenordssalt.

        
$user = new User(); # Här skapas ett tomt användarobjekt som senare fylls på.
        
$user->username $username;
        
$user->password hash_password($password$salt);
        
$user->salt $salt;
        
$user->accounts = array(
            new 
Account("Bankkort", array( # Huvudbankkontot skapas och ges en välkomstbonus på 1000 kr.
                
new Transaction(
                    
"Välkomstbonus",
                    
1000
                
)
            ), 
true)
        );
        
$user->saveData();

        return 
$user;
    }

    public static function 
TryLoginUser($username$password): ?User
    
# Statisk funktion som försöker logga in användare med användarnamn och lösenord.
    
{
        if (!
self::UserExists($username)) # Kontrollerar att användaren finns.
            
return null;
        
$user self::LoadUser($username); # Laddar datan.
        
$hashed hash_password($password$user->salt); # Hashar lösenordet och kollar att de stämmer överens.
        
if ($user->password != $hashed)
            return 
null;

        return 
$user;
    }

    public static function 
UserExists($username): bool
    
# Statisk funktion som kollar ifall en användare finns utifrån användarnamn.
    
{
        return 
file_exists(sprintf(self::$storagestrtolower($username)));
    }

    public function 
createAccount($name): Account
    
# Funktion som skapar ett nytt (bank)konto. Koden förklarar sig själv.
    
{
        
$account = new Account($name);
        
array_push($this->accounts$account);
        
$this->saveData();
        return 
$account;
    }

    public function 
getAccountFromId($id): ?Account
    
# Funktion som hämtar ett kontoobjekt från konto-ID.
    
{
        foreach (
$this->accounts as $account) { # Itererar genom alla och hämtar det med matchande ID.
            
if ($account->id == $id)
                return 
$account;
        }
        return 
null;
    }

    public function 
getMainAccount(): ?Account
    
# Hämtar huvudkontot. Huvudkontot är ett konto som insättningar, uttag och mottag av externa transaktioner sker från.
    # Det kan inte tas bort. 
    
{
        foreach (
$this->accounts as $account) {
            if (
$account->mainAccount) {
                return 
$account;
            }
        }
        return 
null# Bör aldrig inträffa
    
}

    public function 
logDeposit($amount): void
    
# Sparar ett uttag från huvudkontot.
    
{
        
$account $this->getMainAccount();
        
$account->logTransaction(new Transaction("Insättning"$amount));
        
$this->saveData();
    }

    public function 
logWithdrawal($amount): void
    
# Sparar en insättning till huvudkontot.
    
{
        
$account $this->getMainAccount();
        
$account->logTransaction(new Transaction("Uttag", -$amount));
        
$this->saveData();
    }

    public function 
logInternalTransaction($senderAccount$recipientAccount$amount$message "Intern transaktion"): void
    
# Sparar en intern transkation (mellan två konton hos samma användare).
    
{
        
# Pengar tas från sändaren och ges till mottagaren.
        
$senderAccount->logTransaction(new Transaction($message, -$amount$recipientAccount->id));
        
$recipientAccount->logTransaction(new Transaction($message$amount$senderAccount->id));
        
$this->saveData();
    }

    public function 
logExternalTransaction($senderAccount$recipientUser$amount): void
    
# Sparar en extern transkation (från en användare till en annan).
    
{
        
# Pengar tas från sändarkontot.
        
$senderAccount->logTransaction(new Transaction("Transaktion", -$amount$recipientUser->username));
        
$this->saveData();

        
# Transaktionen sker till huvudkontot hos mottagaren.
        
$recipientAccount $recipientUser->getMainAccount();
        
$recipientAccount->logTransaction(new Transaction("Transaktion"$amount$this->username));
        
$recipientUser->saveData();
    }

    public function 
saveData(): void
    
# Sparar en användare.
    
{
        
$file sprintf(self::$storagestrtolower($this->username));
        
# Eftersom hela objektet innehåller all information kan $this sparas till filen.
        
file_put_contents($filejson_encode($thisJSON_PRETTY_PRINT JSON_UNESCAPED_UNICODE));
    }
}

class 
Account
    
# Klass för en användares bankkonto
{
    public 
$name;
    public 
$id;
    public 
$transactions# Lista på transaktioner.
    
public $mainAccount# Bool. Ska finnas exakt ett konto som är true.
    
public $active# Bool. Bestämmer ifall kontot är aktivt eller inte. Konton tas aldrig bort, utan active sätts till false.
    
public function __construct($name$transactions null$isMainAccount false$id null$active true)
    {
        
$this->name $name;
        
$this->id $id ?? generate_uuid();
        
$this->transactions $transactions ?? array();
        
$this->mainAccount $isMainAccount;
        
$this->active $active;
    }

    public function 
getBalance(): int
    
# Hämtar saldot för kontot genom att summera alla transaktioner.
    
{
        
$balance 0;
        foreach (
$this->transactions as $transaction) {
            
$balance += $transaction->sum;
        }
        return 
$balance;
    }

    public function 
logTransaction($transaction): void
    
# Sparar en transaktion till kontot.
    # Transaktionen sparas inte, utan User->saveData() måste köras.
    
{
        
array_push($this->transactions$transaction);
    }
}

class 
Transaction
    
# Klass för transaktioner.
    # Innehåller inte särskilt mycket funktionalitet, men fills för att hålla transaktioner i objekt-form.
{
    public 
$name;
    public 
$sum# Mängden pengar som överförts. Är negativt ifall pengar har skickats från kontot.
    
public $otherId# Konto-ID för andra kontot i transaktionen.
    # Eftersom detta objekt ligger i en array i varje konto, vet man redan vilket ena kontot är.
    
public $date;

    public function 
__construct($name$sum$otherId null$date null)
    {
        
$this->name $name;
        
$this->sum $sum;
        
$this->otherId $otherId;
        
$this->date $date ?? date("Y-m-d"); # Markerar nuvarande datumet ifall inget annat angetts.
    
}
}
?>