<commit_before><?php
/*
 * Copyright (c) <NAME>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is furnished
 * to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

namespace Mbank;

class Mbank
{
    protected $curl;

    protected $cookie;

    protected $document;

    protected $xpath;

    protected $opts = array(
        CURLOPT_URL => null,
        CURLOPT_POST => false,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HEADER => true,
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_HTTPHEADER => array('Expect:'),
    );

    const URL = 'https://www.mbank.com.pl';

    public function __construct()
    {
        $this->curl = curl_init();

        $this->document = new \DOMDocument();
        $this->document->preserveWhiteSpace = false;
    }

    public function __destruct()
    {
        curl_close($this->curl);
    }

    public function login($customer, $password)
    {
        $opts = array(
            CURLOPT_URL => self::URL,
            CURLOPT_REFERER => 'http://www.mbank.pl/login/',
        );
        $this->curl($opts);

        $opts = array(
            CURLOPT_URL => self::URL . '/logon.aspx',
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => array(
                '__PARAMETERS' => $this->xpath->evaluate('string(//input[@name="__PARAMETERS"]/@value)'),
                '__STATE' => $this->xpath->evaluate('string(//input[@name="__STATE"]/@value)'),
                '__VIEWSTATE' => $this->xpath->evaluate('string(//input[@name="__VIEWSTATE"]/@value)'),
                '__EVENTVALIDATION' => $this->xpath->evaluate('string(//input[@name="__EVENTVALIDATION"]/@value)'),
                'customer' => $customer,
                'password' => <PASSWORD>,
                'seed' => $this->xpath->evaluate('string(//input[@name="seed"]/@value)'),
            ),
        );
        $this->curl($opts);

        if (!preg_match('/mBank2(?!\s+NotValid)/', $this->cookie)) {
            throw new \Exception('login() failed');
        }

        return true;
    }

    public function accounts()
    {
        $opts = array(
            CURLOPT_URL => self::URL . '/accounts_list.aspx',
        );
        $this->curl($opts);

        $accounts = array();

        $nodes = $this->xpath->query('//div[@id="AccountsGrid"]/ul/li[p[@class="Account"]/a]');

        foreach ($nodes as $node) {
            $onclick = $this->xpath->evaluate('string(p[@class="Amount"]/a/@onclick)', $node);
            preg_match("/'POST','(?<parameters>[^']+)'/", $onclick, $matches);
            $parameters = $matches['parameters'];

            $name = $this->xpath->evaluate('string(p[@class="Account"]/a)', $node);
            $iban = preg_replace('/[^\d]/', '', $name);
            $name = preg_replace('/[\d ]{26,}/', '', $name);

            $value = $this->xpath->evaluate('string(p[@class="Amount"]/span)', $node);
            preg_match('/ (?<currency>\w{3})$/', $value, $matches);
            $currency = $matches['currency'];
            $value = self::tofloat($value);

            $balance = $this->xpath->evaluate('string(p[@class="Amount"]/a)', $node);
            $balance = self::tofloat($balance);

            $accounts[$iban] = array(
                'name' => $name,
                'iban' => $iban,
                'value' => $value,
                'balance' => $balance,
                'currency' => $currency,
                'operations_params' => array(
                    '__PARAMETERS' => $parameters,
                    '__STATE' => $this->xpath->evaluate('string(//input[@name="__STATE"]/@value)'),
                    '__VIEWSTATE' => $this->xpath->evaluate('string(//input[@name="__VIEWSTATE"]/@value)'),
                ),
            );
        }

        return $accounts;
    }

    public function operations($account)
    {
        $opts = array(
            CURLOPT_URL => self::URL . '/account_oper_list.aspx',
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => $account['operations_params'],
        );
        $this->curl($opts);

        $operations = array();

        $nodes = $this->xpath->query('//div[@id="account_operations"]/ul/li[p[@class="Date"]/span]');

        foreach ($nodes as $node) {
            $type = $this->xpath->evaluate('string(p[@class="OperationDescription"]/a)', $node);
            $type = trim($type);

            $elements = $this->xpath->evaluate('count(p[@class="OperationDescription"]/span)', $node);
            
            if($elements == 3){
                $name = '';
                $iban = $this->xpath->evaluate('string(p[@class="OperationDescription"]/span[1])', $node);
                $title = $this->xpath->evaluate('string(p[@class="OperationDescription"]/span[2])', $node);
            } elseif($elements == 4){
                $name = $this->xpath->evaluate('string(p[@class="OperationDescription"]/span[1])', $node);
                $iban = $this->xpath->evaluate('string(p[@class="OperationDescription"]/span[2])', $node);
                $title = $this->xpath->evaluate('string(p[@class="OperationDescription"]/span[3])', $node);
            }
            
            $title = trim($title);
            $title = preg_replace('/\s{2,}/', "\n", $title);
            $iban = preg_replace('/[^\d]/', '', $iban);
            
            $value = $this->xpath->evaluate('string(p[@class="Amount"][1]/span)', $node);
            preg_match('/ (?<currency>\w{3})$/', $value, $matches);
            $currency = $matches['currency'];
            $value = self::tofloat($value);
            $flow = $value > 0;

            $balance = $this->xpath->evaluate('string(p[@class="Amount"][2]/span)', $node);
            $balance = self::tofloat($balance);

            $created = $this->xpath->evaluate('string(p[@class="Date"]/span[1])', $node);
            $created = date('Y-m-d', strtotime($created));

            $released = $this->xpath->evaluate('string(p[@class="Date"]/span[2])', $node);
            $released = date('Y-m-d', strtotime($released));

            $operations[] = compact(
                'type',
                'name',
                'title',
                'iban',
                'value',
                'flow',<commit_msg>Removed 'flow' and fixed formatting<commit_after><?php
/*
 * Copyright (c) <NAME>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is furnished
 * to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

namespace Mbank;

class Mbank
{
    protected $curl;

    protected $cookie;

    protected $document;

    protected $xpath;

    protected $opts = array(
        CURLOPT_URL => null,
        CURLOPT_POST => false,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HEADER => true,
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_HTTPHEADER => array('Expect:'),
    );

    const URL = 'https://www.mbank.com.pl';

    public function __construct()
    {
        $this->curl = curl_init();

        $this->document = new \DOMDocument();
        $this->document->preserveWhiteSpace = false;
    }

    public function __destruct()
    {
        curl_close($this->curl);
    }

    public function login($customer, $password)
    {
        $opts = array(
            CURLOPT_URL => self::URL,
            CURLOPT_REFERER => 'http://www.mbank.pl/login/',
        );
        $this->curl($opts);

        $opts = array(
            CURLOPT_URL => self::URL . '/logon.aspx',
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => array(
                '__PARAMETERS' => $this->xpath->evaluate('string(//input[@name="__PARAMETERS"]/@value)'),
                '__STATE' => $this->xpath->evaluate('string(//input[@name="__STATE"]/@value)'),
                '__VIEWSTATE' => $this->xpath->evaluate('string(//input[@name="__VIEWSTATE"]/@value)'),
                '__EVENTVALIDATION' => $this->xpath->evaluate('string(//input[@name="__EVENTVALIDATION"]/@value)'),
                'customer' => $customer,
                'password' => <PASSWORD>,
                'seed' => $this->xpath->evaluate('string(//input[@name="seed"]/@value)'),
            ),
        );
        $this->curl($opts);

        if (!preg_match('/mBank2(?!\s+NotValid)/', $this->cookie)) {
            throw new \Exception('login() failed');
        }

        return true;
    }

    public function accounts()
    {
        $opts = array(
            CURLOPT_URL => self::URL . '/accounts_list.aspx',
        );
        $this->curl($opts);

        $accounts = array();

        $nodes = $this->xpath->query('//div[@id="AccountsGrid"]/ul/li[p[@class="Account"]/a]');

        foreach ($nodes as $node) {
            $onclick = $this->xpath->evaluate('string(p[@class="Amount"]/a/@onclick)', $node);
            preg_match("/'POST','(?<parameters>[^']+)'/", $onclick, $matches);
            $parameters = $matches['parameters'];

            $name = $this->xpath->evaluate('string(p[@class="Account"]/a)', $node);
            $iban = preg_replace('/[^\d]/', '', $name);
            $name = preg_replace('/[\d ]{26,}/', '', $name);

            $value = $this->xpath->evaluate('string(p[@class="Amount"]/span)', $node);
            preg_match('/ (?<currency>\w{3})$/', $value, $matches);
            $currency = $matches['currency'];
            $value = self::tofloat($value);

            $balance = $this->xpath->evaluate('string(p[@class="Amount"]/a)', $node);
            $balance = self::tofloat($balance);

            $accounts[$iban] = array(
                'name' => $name,
                'iban' => $iban,
                'value' => $value,
                'balance' => $balance,
                'currency' => $currency,
                'operations_params' => array(
                    '__PARAMETERS' => $parameters,
                    '__STATE' => $this->xpath->evaluate('string(//input[@name="__STATE"]/@value)'),
                    '__VIEWSTATE' => $this->xpath->evaluate('string(//input[@name="__VIEWSTATE"]/@value)'),
                ),
            );
        }

        return $accounts;
    }

    public function operations($account)
    {
        $opts = array(
            CURLOPT_URL => self::URL . '/account_oper_list.aspx',
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => $account['operations_params'],
        );
        $this->curl($opts);

        $operations = array();

        $nodes = $this->xpath->query('//div[@id="account_operations"]/ul/li[p[@class="Date"]/span]');

        foreach ($nodes as $node) {
            $type = $this->xpath->evaluate('string(p[@class="OperationDescription"]/a)', $node);
            $type = trim($type);

            $elements = $this->xpath->evaluate('count(p[@class="OperationDescription"]/span)', $node);

            if ($elements == 3) {
                $name = '';
                $iban = $this->xpath->evaluate('string(p[@class="OperationDescription"]/span[1])', $node);
                $title = $this->xpath->evaluate('string(p[@class="OperationDescription"]/span[2])', $node);
            } elseif ($elements == 4) {
                $name = $this->xpath->evaluate('string(p[@class="OperationDescription"]/span[1])', $node);
                $iban = $this->xpath->evaluate('string(p[@class="OperationDescription"]/span[2])', $node);
                $title = $this->xpath->evaluate('string(p[@class="OperationDescription"]/span[3])', $node);
            }

            $title = trim($title);
            $title = preg_replace('/\s{2,}/', "\n", $title);
            $iban = preg_replace('/[^\d]/', '', $iban);

            $value = $this->xpath->evaluate('string(p[@class="Amount"][1]/span)', $node);
            preg_match('/ (?<currency>\w{3})$/', $value, $matches);
            $currency = $matches['currency'];
            $value = self::tofloat($value);

            $balance = $this->xpath->evaluate('string(p[@class="Amount"][2]/span)', $node);
            $balance = self::tofloat($balance);

            $created = $this->xpath->evaluate('string(p[@class="Date"]/span[1])', $node);
            $created = date('Y-m-d', strtotime($created));

            $released = $this->xpath->evaluate('string(p[@class="Date"]/span[2])', $node);
            $released = date('Y-m-d', strtotime($released));

            $operations[] = compact(
                'type',
                'name',
                'title',
                'iban',
                'value',
{'fraction_non_alphanumeric': 0.17915853998328224, 'fraction_numerical': 0.002438005015324603, 'mean_word_length': 2.3149388132071116, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 194, 'https://': 2, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4183978', 'n_tokens_mistral': 4353, 'n_tokens_neox': 4060, 'n_words': 853}