Example #1
0
function magicBuildPage($request)
{
    $orderConnection = mappedConnection('orders');
    $usersConnection = mappedConnection('users');
    $query = $request['query'];
    // пагинация по айдишникам, что бы не было сдвигов/повторов при добавлении/удаленнии элементов в ленте
    $minId = array_key_exists('min_id', $query) ? (int) $query['min_id'] : null;
    $maxId = array_key_exists('max_id', $query) ? (int) $query['max_id'] : null;
    $pageSize = 10;
    // селектим на 1 элемент больше,
    // что бы понять, достигнут ли конец и не селектить count
    $pageSeizeInc = $pageSize + 1;
    $orders = loadOrders($orderConnection, $pageSeizeInc, $minId, $maxId);
    $isLastPage = count($orders) < $pageSeizeInc;
    // удаляем лишний элемент
    if (!$isLastPage) {
        array_pop($orders);
    }
    $userIds = [];
    foreach ($orders as $order) {
        if (($id = $order['created_by']) && !in_array($id, $userIds, true)) {
            $userIds[] = $id;
        }
    }
    $users = loadUsersByIds($usersConnection, $userIds);
    $vars = ['users' => $users, 'orders' => $orders, 'is_last_page' => $isLastPage];
    if (array_key_exists('HTTP_ACCEPT', $request['server']) && strpos(strtolower($request['server']['HTTP_ACCEPT']), 'application/json') !== false) {
        return createResponse(json_encode($vars), 200, ['content-type' => 'application/json']);
    } else {
        $vars['form'] = createCreateForm();
        return createResponse(render('orders/list.html.php', $vars));
    }
}
Example #2
0
function getLastId()
{
    $connection = mappedConnection('queue');
    $sql = 'SELECT auto_increment FROM information_schema.tables WHERE table_name = \'queue\';';
    $query = mysqli_query($connection, $sql);
    $result = mysqli_fetch_array($query, MYSQLI_NUM)[0];
    mysqli_free_result($query);
    return $result - 1;
}
Example #3
0
function queueNotify($type, $data)
{
    $connection = mappedConnection('queue');
    $sql = 'INSERT INTO queue (event) VALUES (?);';
    $statement = mysqli_prepare($connection, $sql);
    $value = serialize(['type' => $type, 'data' => $data]);
    mysqli_stmt_bind_param($statement, 's', $value);
    mysqli_stmt_execute($statement);
    mysqli_stmt_free_result($statement);
}
Example #4
0
<?php

/**
 * Скрипт для обработки оторваных транзакций.
 * @todo механизм локов, что бы скрипт не мешал работе аппликейшна.
 */
define('SRC_DIR', __DIR__ . '/../src');
define('APP_DIR', __DIR__ . '/../app');
define('WEB_DIR', __DIR__ . '/../web');
define('TML_DIR', SRC_DIR . '/templates');
require_once SRC_DIR . '/database.php';
$userConnection = mappedConnection('users');
$orderConnection = mappedConnection('orders');
// если коннекты совпадают, то ничего делать не нужно, у нас общая транзакция.
if ($userConnection === $orderConnection) {
    exit;
}
// получаем список текущих транзакций.
// если не получилось, значит с одной из баз что-то не так, прерываем работу.
$userResult = mysqli_query($userConnection, 'xa recover;');
if ($userResult) {
    $userRecover = mysqli_fetch_all($userResult);
    mysqli_free_result($userResult);
} else {
    exit;
}
if ($orderResult = mysqli_query($orderConnection, 'xa recover;')) {
    $orderRecover = mysqli_fetch_all($orderResult);
    mysqli_free_result($orderResult);
} else {
    exit;
Example #5
0
<?php

include_once __DIR__ . '/pay_form.php';
include_once SRC_DIR . '/forms.php';
include_once SRC_DIR . '/database.php';
function addCash($connection, $userId, $sum)
{
    $sql = 'UPDATE users SET cash = cash + ' . $sum . ' WHERE id = ' . $userId . ';';
    mysqli_query($connection, $sql);
    return (bool) mysqli_affected_rows($connection);
}
return function (array $request) {
    $form = createPayForm();
    formHandleRequest($form, $request);
    if (formIsValid($form)) {
        $vars = extractValues($form);
        $sum = (int) ((double) $vars['pay'] * 100);
        $user = currentUser();
        $userId = (int) $user['id'];
        $connection = mappedConnection('users');
        addCash($connection, $userId, $sum);
        return createResponse();
    }
    return createResponse('', 400);
};
Example #6
0
    $sql = 'SELECT id, name, email, hashed_password FROM users WHERE email = ? LIMIT 1';
    $statement = mysqli_prepare($connection, $sql);
    mysqli_stmt_bind_param($statement, 's', $email);
    mysqli_stmt_execute($statement);
    mysqli_stmt_bind_result($statement, $id, $name, $email, $hp);
    mysqli_stmt_fetch($statement);
    mysqli_stmt_close($statement);
    if (isset($id, $name, $email, $hp)) {
        return ['id' => $id, 'name' => $name, 'email' => $email, 'hashed_password' => $hp];
    }
    return null;
}
return function (array $request) {
    if (currentUser()) {
        return createRedirectResponse('/index.php/');
    }
    $form = createCreateForm();
    formHandleRequest($form, $request);
    if (formIsValid($form)) {
        $auth = extractValues($form);
        $user = findUserByEmail(mappedConnection('users'), $auth['email']);
        if ($user && password_verify($auth['password'], $user['hashed_password'])) {
            authorize($user);
            return createRedirectResponse('/');
        } else {
            $form['valid'] = false;
            $form['fields']['password']['errors'][] = 'Неверный Пароль';
        }
    }
    return createResponse(render('session/new.html.php', ['form' => $form]));
};
Example #7
0
function deleteOrder($id, $ownerId)
{
    $orderConnection = mappedConnection('orders');
    $userConnection = mappedConnection('users');
    $price = findOrderPriceById($orderConnection, $id, $ownerId);
    if (!$price) {
        return false;
    }
    $sqlOrders = 'UPDATE orders SET deleted = TRUE WHERE id = ' . (int) $id . ' AND done_by IS NULL AND deleted IS FALSE;';
    $sqlUsers = 'UPDATE users SET cash = cash + ' . $price . ' WHERE id = ' . $ownerId . ';';
    if ($orderConnection === $userConnection) {
        mysqli_begin_transaction($orderConnection);
        mysqli_query($orderConnection, $sqlOrders);
        if ($result = (bool) mysqli_affected_rows($orderConnection)) {
            mysqli_query($orderConnection, $sqlUsers);
            mysqli_commit($orderConnection);
            return true;
        }
        mysqli_rollback($orderConnection);
        return false;
    } else {
        $result = false;
        $uuid = uniqid('', false);
        $transactionOrder = '\'' . $uuid . '\', \'oi\'';
        $transactionUser = '******'' . $uuid . '\', \'ui\'';
        mysqli_query($userConnection, 'DO GET_LOCK(\'' . $uuid . '-u\', 1);');
        mysqli_query($orderConnection, 'DO GET_LOCK(\'' . $uuid . '-o\', 1);');
        // стартуем транзакцию на базе с заказами
        mysqli_query($orderConnection, 'XA START ' . $transactionOrder . ';');
        // удаляем заказ
        mysqli_query($orderConnection, $sqlOrders);
        $completed = mysqli_affected_rows($orderConnection);
        mysqli_query($orderConnection, 'XA END ' . $transactionOrder . ';');
        // если получилось удалить
        if ($completed) {
            mysqli_query($userConnection, 'XA START ' . $transactionUser . ';');
            mysqli_query($userConnection, $sqlUsers);
            mysqli_query($userConnection, 'XA END ' . $transactionUser . ';');
            // подготавиливаем обе транзакции
            if (mysqli_query($orderConnection, 'XA PREPARE ' . $transactionOrder . ';')) {
                if (mysqli_query($userConnection, 'XA PREPARE ' . $transactionUser . ';')) {
                    // пытаемся закоммитить удаление заказа
                    if (mysqli_query($orderConnection, 'XA COMMIT ' . $transactionOrder . ';')) {
                        // плюсуем деньги, если в этот момет БД упала, то коммитим при поднятии.
                        mysqli_query($userConnection, 'XA COMMIT ' . $transactionUser . ';');
                        $result = true;
                    } else {
                        // если что-то пошло не так, откатываем
                        mysqli_query($userConnection, 'XA ROLLBACK ' . $transactionUser . ';');
                    }
                } else {
                    mysqli_query($orderConnection, 'XA ROLLBACK ' . $transactionOrder . ';');
                }
            } else {
                mysqli_query($userConnection, 'XA ROLLBACK ' . $transactionUser . ';');
            }
        } else {
            // коммитим, изменений все равно нет.
            mysqli_query($orderConnection, 'XA COMMIT ' . $transactionOrder . ' ONE PHASE;');
        }
        mysqli_query($userConnection, 'DO RELEASE_LOCK(\'' . $uuid . '-u\');');
        mysqli_query($orderConnection, 'DO RELEASE_LOCK(\'' . $uuid . '-o\');');
        return $result;
    }
}
Example #8
0
function completeOrder($id, $userId)
{
    $id = (int) $id;
    $userId = (int) $userId;
    $userConnection = mappedConnection('users');
    $orderConnection = mappedConnection('orders');
    $price = findOrderPriceById($orderConnection, $id, $userId);
    if (!$price) {
        return false;
    }
    $commission = calculateCommission($price);
    $reward = $price - $commission;
    $sqlOrders = 'UPDATE orders SET done_by = ' . $userId . ', commission = ' . $commission . ' WHERE id = ' . $id . ' AND done_by IS NULL AND orders.deleted IS FALSE;';
    $sqlUsers = 'UPDATE users SET cash = cash + ' . $reward . ' WHERE id = ' . $userId . ';';
    if ($userConnection === $orderConnection) {
        mysqli_begin_transaction($orderConnection);
        mysqli_query($orderConnection, $sqlOrders);
        if ($result = (bool) mysqli_affected_rows($orderConnection)) {
            mysqli_query($orderConnection, $sqlUsers);
            mysqli_commit($orderConnection);
            return true;
        }
        mysqli_rollback($orderConnection);
        return false;
    } else {
        $uuid = uniqid('', false);
        // Лочим uuid, что бы скрипт поднятия оторваных транзакций не мешал ;)
        mysqli_query($userConnection, 'DO GET_LOCK(\'' . $uuid . '-u\', 1);');
        mysqli_query($orderConnection, 'DO GET_LOCK(\'' . $uuid . '-o\', 1);');
        $transactionOrder = '\'' . $uuid . '\', \'oc\'';
        $transactionUser = '******'' . $uuid . '\', \'uc\'';
        // стартуем транзакцию на базе с заказами
        mysqli_query($orderConnection, 'XA START ' . $transactionOrder . ';');
        // помечаем заказ выполненым
        mysqli_query($orderConnection, $sqlOrders);
        $completed = mysqli_affected_rows($orderConnection);
        mysqli_query($orderConnection, 'XA END ' . $transactionOrder . ';');
        $result = false;
        // если получилось пометить как выполненое
        if ($completed) {
            mysqli_query($userConnection, 'XA START ' . $transactionUser . ';');
            mysqli_query($userConnection, $sqlUsers);
            mysqli_query($userConnection, 'XA END ' . $transactionUser . ';');
            // подготавиливаем обе транзакции
            if (mysqli_query($orderConnection, 'XA PREPARE ' . $transactionOrder . ';')) {
                if (mysqli_query($userConnection, 'XA PREPARE ' . $transactionUser . ';')) {
                    // пытаемся закоммитить изменения заказа
                    if (mysqli_query($orderConnection, 'XA COMMIT ' . $transactionOrder . ';')) {
                        // плюсуем деньги, если в этот момет БД упала, то коммитим при поднятии.
                        mysqli_query($userConnection, 'XA COMMIT ' . $transactionUser . ';');
                        $result = true;
                    } else {
                        // если что-то пошло не так, пробуем откатить
                        mysqli_query($userConnection, 'XA ROLLBACK ' . $transactionUser . ';');
                    }
                } else {
                    mysqli_query($orderConnection, 'XA ROLLBACK ' . $transactionOrder . ';');
                }
            } else {
                mysqli_query($userConnection, 'XA ROLLBACK ' . $transactionUser . ';');
            }
        } else {
            // коммитим, изменений все равно нет.
            mysqli_query($orderConnection, 'XA COMMIT ' . $transactionOrder . ' ONE PHASE;');
        }
        mysqli_query($userConnection, 'DO RELEASE_LOCK(\'' . $uuid . '-u\');');
        mysqli_query($orderConnection, 'DO RELEASE_LOCK(\'' . $uuid . '-o\');');
        return $result;
    }
}
Example #9
0
/**
 * @param string $name
 * @param string $description
 * @param int $price
 * @param int $ownerId
 * @return bool|int
 */
function createOrder($name, $description, $price, $ownerId)
{
    $sql = 'INSERT INTO orders (title, description, created_by, price) VALUES (?, ?, ?, ?)';
    $sqlUsers = 'UPDATE users SET cash = cash - ' . $price . ' WHERE id = ' . $ownerId . ' AND cash >= ' . $price . ';';
    $orderConnection = mappedConnection('orders');
    $userConnection = mappedConnection('users');
    if ($orderConnection === $userConnection) {
        mysqli_begin_transaction($orderConnection);
        if (mysqli_query($userConnection, $sqlUsers) && mysqli_affected_rows($userConnection)) {
            $statement = mysqli_prepare($orderConnection, $sql);
            mysqli_stmt_bind_param($statement, 'ssdd', $name, $description, $ownerId, $price);
            mysqli_stmt_execute($statement);
            mysqli_commit($orderConnection);
            return mysqli_stmt_insert_id($statement);
        } else {
            mysqli_rollback($userConnection);
            return false;
        }
    } else {
        $result = false;
        $uuid = uniqid('', false);
        $transactionOrder = '\'' . $uuid . '\', \'oi\'';
        $transactionUser = '******'' . $uuid . '\', \'ui\'';
        mysqli_query($userConnection, 'DO GET_LOCK(\'' . $uuid . '-u\', 1);');
        mysqli_query($orderConnection, 'DO GET_LOCK(\'' . $uuid . '-o\', 1);');
        // стартуем транзацкцию на базе с юзерами.
        mysqli_query($userConnection, 'XA START ' . $transactionUser . ';');
        // списываем деньги, если они есть
        mysqli_query($userConnection, $sqlUsers);
        $done = (bool) mysqli_affected_rows($userConnection);
        mysqli_query($userConnection, 'XA END ' . $transactionUser . ';');
        // если списать деньги удалось, то пробуем опубликовать заказ
        if ($done) {
            // стартуем транзакцию на базе с заказами
            mysqli_query($orderConnection, 'XA START ' . $transactionOrder . ';');
            // сейвим
            $statement = mysqli_prepare($orderConnection, $sql);
            mysqli_stmt_bind_param($statement, 'ssdd', $name, $description, $ownerId, $price);
            mysqli_stmt_execute($statement);
            $result = mysqli_stmt_insert_id($statement);
            mysqli_query($orderConnection, 'XA END ' . $transactionOrder . ';');
            // подготавиливаем обе транзакции
            if (mysqli_query($userConnection, 'XA PREPARE ' . $transactionUser . ';')) {
                if (mysqli_query($orderConnection, 'XA PREPARE ' . $transactionOrder . ';')) {
                    // пытаемся закоммитить списание денег
                    if (mysqli_query($userConnection, 'XA COMMIT ' . $transactionUser . ';')) {
                        // публикуем заказ, если в этот момет БД упала, то коммитим при поднятии.
                        mysqli_query($orderConnection, 'XA COMMIT ' . $transactionOrder . ';');
                    } else {
                        // если что-то пошло не так, откатываем
                        mysqli_query($orderConnection, 'XA ROLLBACK ' . $transactionOrder . ';');
                        $result = false;
                    }
                } else {
                    mysqli_query($userConnection, 'XA ROLLBACK ' . $transactionUser . ';');
                    $result = false;
                }
            } else {
                mysqli_query($orderConnection, 'XA ROLLBACK ' . $transactionOrder . ';');
                $result = false;
            }
        } else {
            // коммитим, изменений все равно нет.
            mysqli_query($userConnection, 'XA COMMIT ' . $transactionUser . ' ONE PHASE;');
        }
        mysqli_query($userConnection, 'DO RELEASE_LOCK(\'' . $uuid . '-u\');');
        mysqli_query($orderConnection, 'DO RELEASE_LOCK(\'' . $uuid . '-o\');');
        return $result;
    }
}
Example #10
0
function mysql_session_destroy($sessionId)
{
    $connection = mappedConnection('sessions');
    $statement = mysqli_prepare($connection, 'DELETE FROM sessions WHERE id = ?;');
    mysqli_stmt_bind_param($statement, 's', $sessionId);
    mysqli_stmt_execute($statement);
    mysqli_stmt_close($statement);
    return true;
}