Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c75634a6b6 | ||
|
|
9c156ace51 | ||
|
|
9660f06ca5 | ||
|
|
222ac63dcc | ||
|
|
b29f71a773 |
17
admin/customer_delete.php
Normal file
17
admin/customer_delete.php
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
include __DIR__ . '/../db/config.php';
|
||||||
|
|
||||||
|
if (!isset($_GET['id'])) {
|
||||||
|
header('Location: customers.php');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$pdo = db();
|
||||||
|
|
||||||
|
// The ON DELETE CASCADE constraint on the orders table will automatically delete related orders.
|
||||||
|
$stmt = $pdo->prepare('DELETE FROM customers WHERE id = ?');
|
||||||
|
$stmt->execute([$_GET['id']]);
|
||||||
|
|
||||||
|
header('Location: customers.php');
|
||||||
|
exit;
|
||||||
|
?>
|
||||||
65
admin/customer_edit.php
Normal file
65
admin/customer_edit.php
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
<?php
|
||||||
|
include __DIR__ . '/../db/config.php';
|
||||||
|
include 'header.php';
|
||||||
|
|
||||||
|
$pdo = db();
|
||||||
|
$customer = [
|
||||||
|
'id' => '',
|
||||||
|
'name' => '',
|
||||||
|
'email' => '',
|
||||||
|
'service_address' => ''
|
||||||
|
];
|
||||||
|
$page_title = 'Edit Customer';
|
||||||
|
|
||||||
|
if (!isset($_GET['id'])) {
|
||||||
|
echo "<div class='alert alert-danger'>No customer ID specified.</div>";
|
||||||
|
include 'footer.php';
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$stmt = $pdo->prepare('SELECT * FROM customers WHERE id = ?');
|
||||||
|
$stmt->execute([$_GET['id']]);
|
||||||
|
$customer = $stmt->fetch();
|
||||||
|
|
||||||
|
if (!$customer) {
|
||||||
|
echo "<div class='alert alert-danger'>Customer not found.</div>";
|
||||||
|
include 'footer.php';
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||||
|
$name = $_POST['name'] ?? '';
|
||||||
|
$email = $_POST['email'] ?? '';
|
||||||
|
$service_address = $_POST['service_address'] ?? '';
|
||||||
|
$customer_id = $_POST['id'] ?? null;
|
||||||
|
|
||||||
|
if ($customer_id) {
|
||||||
|
$stmt = $pdo->prepare('UPDATE customers SET name = ?, email = ?, service_address = ? WHERE id = ?');
|
||||||
|
$stmt->execute([$name, $email, $service_address, $customer_id]);
|
||||||
|
header('Location: customers.php');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
<h1><?php echo $page_title; ?></h1>
|
||||||
|
|
||||||
|
<form action="customer_edit.php?id=<?php echo htmlspecialchars($customer['id']); ?>" method="post">
|
||||||
|
<input type="hidden" name="id" value="<?php echo htmlspecialchars($customer['id']); ?>">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="name" class="form-label">Name</label>
|
||||||
|
<input type="text" class="form-control" id="name" name="name" value="<?php echo htmlspecialchars($customer['name']); ?>" required>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="email" class="form-label">Email</label>
|
||||||
|
<input type="email" class="form-control" id="email" name="email" value="<?php echo htmlspecialchars($customer['email']); ?>" required>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="service_address" class="form-label">Service Address</label>
|
||||||
|
<input type="text" class="form-control" id="service_address" name="service_address" value="<?php echo htmlspecialchars($customer['service_address']); ?>" required>
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="btn btn-primary">Save Customer</button>
|
||||||
|
<a href="customers.php" class="btn btn-secondary">Cancel</a>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<?php include 'footer.php'; ?>
|
||||||
48
admin/customers.php
Normal file
48
admin/customers.php
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
<?php
|
||||||
|
include __DIR__ . '/../db/config.php';
|
||||||
|
include 'header.php';
|
||||||
|
|
||||||
|
$pdo = db();
|
||||||
|
$stmt = $pdo->query('SELECT * FROM customers ORDER BY created_at DESC');
|
||||||
|
$customers = $stmt->fetchAll();
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||||
|
<h1>Customers</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<table class="table table-striped table-bordered">
|
||||||
|
<thead class="table-dark">
|
||||||
|
<tr>
|
||||||
|
<th>ID</th>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Email</th>
|
||||||
|
<th>Service Address</th>
|
||||||
|
<th>Joined On</th>
|
||||||
|
<th>Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php if (empty($customers)): ?>
|
||||||
|
<tr>
|
||||||
|
<td colspan="6" class="text-center">No customers found.</td>
|
||||||
|
</tr>
|
||||||
|
<?php else: ?>
|
||||||
|
<?php foreach ($customers as $customer): ?>
|
||||||
|
<tr>
|
||||||
|
<td><?php echo htmlspecialchars($customer['id']); ?></td>
|
||||||
|
<td><?php echo htmlspecialchars($customer['name']); ?></td>
|
||||||
|
<td><?php echo htmlspecialchars($customer['email']); ?></td>
|
||||||
|
<td><?php echo htmlspecialchars($customer['service_address']); ?></td>
|
||||||
|
<td><?php echo htmlspecialchars(date('Y-m-d', strtotime($customer['created_at']))); ?></td>
|
||||||
|
<td>
|
||||||
|
<a href="customer_edit.php?id=<?php echo $customer['id']; ?>" class="btn btn-sm btn-primary">Edit</a>
|
||||||
|
<a href="customer_delete.php?id=<?php echo $customer['id']; ?>" class="btn btn-sm btn-danger" onclick="return confirm('Are you sure?');">Delete</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
<?php endif; ?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<?php include 'footer.php'; ?>
|
||||||
4
admin/footer.php
Normal file
4
admin/footer.php
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
</div>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
49
admin/header.php
Normal file
49
admin/header.php
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Admin Panel</title>
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||||
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
display: flex;
|
||||||
|
min-height: 100vh;
|
||||||
|
background-color: #f8f9fa;
|
||||||
|
}
|
||||||
|
.sidebar {
|
||||||
|
width: 250px;
|
||||||
|
background: #343a40;
|
||||||
|
color: white;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
.sidebar .nav-link {
|
||||||
|
color: #adb5bd;
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
.sidebar .nav-link.active, .sidebar .nav-link:hover {
|
||||||
|
color: #fff;
|
||||||
|
background: #495057;
|
||||||
|
}
|
||||||
|
.sidebar .nav-link .fa {
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
.content {
|
||||||
|
flex-grow: 1;
|
||||||
|
padding: 2rem;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="sidebar">
|
||||||
|
<h4 class="text-center p-3 mb-0">Admin</h4>
|
||||||
|
<nav class="nav flex-column">
|
||||||
|
<a class="nav-link" href="/admin/index.php"><i class="fa fa-tachometer-alt"></i>Dashboard</a>
|
||||||
|
<a class="nav-link" href="/admin/customers.php"><i class="fa fa-users"></i>Customers</a>
|
||||||
|
<a class="nav-link" href="/admin/orders.php"><i class="fa fa-box-open"></i>Orders</a>
|
||||||
|
<a class="nav-link" href="/admin/plans.php"><i class="fa fa-list-alt"></i>Plans</a>
|
||||||
|
<a class="nav-link" href="/admin/pages.php"><i class="fa fa-file-alt"></i>Pages</a>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
<div class="content">
|
||||||
6
admin/index.php
Normal file
6
admin/index.php
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?php include 'header.php'; ?>
|
||||||
|
|
||||||
|
<h1>Dashboard</h1>
|
||||||
|
<p>Welcome to the admin dashboard. Use the sidebar to navigate through the different sections.</p>
|
||||||
|
|
||||||
|
<?php include 'footer.php'; ?>
|
||||||
5
admin/logout.php
Normal file
5
admin/logout.php
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<?php
|
||||||
|
session_start();
|
||||||
|
session_destroy();
|
||||||
|
header('Location: /admin/index.php');
|
||||||
|
exit;
|
||||||
60
admin/orders.php
Normal file
60
admin/orders.php
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
<?php
|
||||||
|
include __DIR__ . '/../db/config.php';
|
||||||
|
include 'header.php';
|
||||||
|
|
||||||
|
$pdo = db();
|
||||||
|
$stmt = $pdo->query('SELECT o.id, c.name as customer_name, p.name as plan_name, o.order_status, o.amount, o.created_at FROM orders o JOIN customers c ON o.customer_id = c.id JOIN plans p ON o.plan_id = p.id ORDER BY o.created_at DESC');
|
||||||
|
$orders = $stmt->fetchAll();
|
||||||
|
|
||||||
|
function get_status_badge($status) {
|
||||||
|
switch (strtolower($status)) {
|
||||||
|
case 'completed':
|
||||||
|
case 'active':
|
||||||
|
return 'bg-success';
|
||||||
|
case 'pending':
|
||||||
|
return 'bg-warning';
|
||||||
|
case 'failed':
|
||||||
|
case 'cancelled':
|
||||||
|
return 'bg-danger';
|
||||||
|
default:
|
||||||
|
return 'bg-secondary';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||||
|
<h1>Orders</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<table class="table table-striped table-bordered">
|
||||||
|
<thead class="table-dark">
|
||||||
|
<tr>
|
||||||
|
<th>Order ID</th>
|
||||||
|
<th>Customer</th>
|
||||||
|
<th>Plan</th>
|
||||||
|
<th>Amount</th>
|
||||||
|
<th>Status</th>
|
||||||
|
<th>Order Date</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php if (empty($orders)): ?>
|
||||||
|
<tr>
|
||||||
|
<td colspan="6" class="text-center">No orders found.</td>
|
||||||
|
</tr>
|
||||||
|
<?php else: ?>
|
||||||
|
<?php foreach ($orders as $order): ?>
|
||||||
|
<tr>
|
||||||
|
<td><?php echo htmlspecialchars($order['id']); ?></td>
|
||||||
|
<td><?php echo htmlspecialchars($order['customer_name']); ?></td>
|
||||||
|
<td><?php echo htmlspecialchars($order['plan_name']); ?></td>
|
||||||
|
<td>$<?php echo htmlspecialchars(number_format($order['amount'], 2)); ?></td>
|
||||||
|
<td><span class="badge <?php echo get_status_badge($order['order_status']); ?>"><?php echo htmlspecialchars(ucfirst($order['order_status'])); ?></span></td>
|
||||||
|
<td><?php echo htmlspecialchars(date('Y-m-d H:i', strtotime($order['created_at']))); ?></td>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
<?php endif; ?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<?php include 'footer.php'; ?>
|
||||||
12
admin/page_delete.php
Normal file
12
admin/page_delete.php
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<?php
|
||||||
|
require_once '../db/config.php';
|
||||||
|
|
||||||
|
$id = $_GET['id'] ?? null;
|
||||||
|
|
||||||
|
if ($id) {
|
||||||
|
$stmt = db()->prepare('DELETE FROM pages WHERE id = ?');
|
||||||
|
$stmt->execute([$id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
header('Location: pages.php');
|
||||||
|
exit;
|
||||||
55
admin/page_edit.php
Normal file
55
admin/page_edit.php
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
<?php
|
||||||
|
require_once '../db/config.php';
|
||||||
|
|
||||||
|
$id = $_GET['id'] ?? null;
|
||||||
|
$page = [];
|
||||||
|
$title = 'Create Page';
|
||||||
|
|
||||||
|
if ($id) {
|
||||||
|
$stmt = db()->prepare('SELECT * FROM pages WHERE id = ?');
|
||||||
|
$stmt->execute([$id]);
|
||||||
|
$page = $stmt->fetch();
|
||||||
|
$title = 'Edit Page';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||||
|
$slug = $_POST['slug'];
|
||||||
|
$page_title = $_POST['title'];
|
||||||
|
$content = $_POST['content'];
|
||||||
|
|
||||||
|
if ($id) {
|
||||||
|
$stmt = db()->prepare('UPDATE pages SET slug = ?, title = ?, content = ? WHERE id = ?');
|
||||||
|
$stmt->execute([$slug, $page_title, $content, $id]);
|
||||||
|
} else {
|
||||||
|
$stmt = db()->prepare('INSERT INTO pages (slug, title, content) VALUES (?, ?, ?)');
|
||||||
|
$stmt->execute([$slug, $page_title, $content]);
|
||||||
|
}
|
||||||
|
|
||||||
|
header('Location: pages.php');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
include 'header.php';
|
||||||
|
?>
|
||||||
|
|
||||||
|
<h1><?php echo $title; ?></h1>
|
||||||
|
|
||||||
|
<form method="POST">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="title" class="form-label">Title</label>
|
||||||
|
<input type="text" class="form-control" id="title" name="title" value="<?php echo htmlspecialchars($page['title'] ?? ''); ?>" required>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="slug" class="form-label">Slug</label>
|
||||||
|
<input type="text" class="form-control" id="slug" name="slug" value="<?php echo htmlspecialchars($page['slug'] ?? ''); ?>" required>
|
||||||
|
<div class="form-text">The slug is the URL-friendly version of the name. It is usually all lowercase and contains only letters, numbers, and hyphens.</div>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="content" class="form-label">Content</label>
|
||||||
|
<textarea class="form-control" id="content" name="content" rows="10" required><?php echo htmlspecialchars($page['content'] ?? ''); ?></textarea>
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="btn btn-primary">Save</button>
|
||||||
|
<a href="pages.php" class="btn btn-secondary">Cancel</a>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<?php include 'footer.php'; ?>
|
||||||
37
admin/pages.php
Normal file
37
admin/pages.php
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
<?php
|
||||||
|
require_once '../db/config.php';
|
||||||
|
|
||||||
|
$pages = db()->query('SELECT * FROM pages ORDER BY title ASC')->fetchAll();
|
||||||
|
|
||||||
|
include 'header.php';
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||||
|
<h1>Pages</h1>
|
||||||
|
<a href="page_edit.php" class="btn btn-primary">Create Page</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<table class="table table-striped">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Title</th>
|
||||||
|
<th>Slug</th>
|
||||||
|
<th>Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php foreach ($pages as $page): ?>
|
||||||
|
<tr>
|
||||||
|
<td><?php echo htmlspecialchars($page['title']); ?></td>
|
||||||
|
<td><?php echo htmlspecialchars($page['slug']); ?></td>
|
||||||
|
<td>
|
||||||
|
<a href="page_edit.php?id=<?php echo $page['id']; ?>" class="btn btn-sm btn-outline-primary">Edit</a>
|
||||||
|
<a href="page_delete.php?id=<?php echo $page['id']; ?>" class="btn btn-sm btn-outline-danger" onclick="return confirm('Are you sure?')">Delete</a>
|
||||||
|
<a href="/page.php?slug=<?php echo htmlspecialchars($page['slug']); ?>" class="btn btn-sm btn-outline-secondary" target="_blank">View</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<?php include 'footer.php'; ?>
|
||||||
15
admin/plan_delete.php
Normal file
15
admin/plan_delete.php
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
include __DIR__ . '/../db/config.php';
|
||||||
|
|
||||||
|
if (!isset($_GET['id'])) {
|
||||||
|
header('Location: plans.php');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$pdo = db();
|
||||||
|
$stmt = $pdo->prepare('DELETE FROM plans WHERE id = ?');
|
||||||
|
$stmt->execute([$_GET['id']]);
|
||||||
|
|
||||||
|
header('Location: plans.php');
|
||||||
|
exit;
|
||||||
|
?>
|
||||||
81
admin/plan_edit.php
Normal file
81
admin/plan_edit.php
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
<?php
|
||||||
|
include __DIR__ . '/../db/config.php';
|
||||||
|
include 'header.php';
|
||||||
|
|
||||||
|
$pdo = db();
|
||||||
|
$plan = [
|
||||||
|
'id' => '',
|
||||||
|
'name' => '',
|
||||||
|
'speed_mbps' => '',
|
||||||
|
'price_monthly' => '',
|
||||||
|
'contract_months' => '',
|
||||||
|
'description' => ''
|
||||||
|
];
|
||||||
|
$page_title = 'Add New Plan';
|
||||||
|
|
||||||
|
if (isset($_GET['id'])) {
|
||||||
|
$page_title = 'Edit Plan';
|
||||||
|
$stmt = $pdo->prepare('SELECT * FROM plans WHERE id = ?');
|
||||||
|
$stmt->execute([$_GET['id']]);
|
||||||
|
$plan = $stmt->fetch();
|
||||||
|
if (!$plan) {
|
||||||
|
echo "<div class='alert alert-danger'>Plan not found.</div>";
|
||||||
|
include 'footer.php';
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||||
|
$name = $_POST['name'] ?? '';
|
||||||
|
$speed_mbps = $_POST['speed_mbps'] ?? 0;
|
||||||
|
$price_monthly = $_POST['price_monthly'] ?? 0;
|
||||||
|
$contract_months = $_POST['contract_months'] ?? 0;
|
||||||
|
$description = $_POST['description'] ?? '';
|
||||||
|
$plan_id = $_POST['id'] ?? null;
|
||||||
|
|
||||||
|
if ($plan_id) {
|
||||||
|
// Update
|
||||||
|
$stmt = $pdo->prepare('UPDATE plans SET name = ?, speed_mbps = ?, price_monthly = ?, contract_months = ?, description = ? WHERE id = ?');
|
||||||
|
$stmt->execute([$name, $speed_mbps, $price_monthly, $contract_months, $description, $plan_id]);
|
||||||
|
} else {
|
||||||
|
// Insert
|
||||||
|
$stmt = $pdo->prepare('INSERT INTO plans (name, speed_mbps, price_monthly, contract_months, description) VALUES (?, ?, ?, ?, ?)');
|
||||||
|
$stmt->execute([$name, $speed_mbps, $price_monthly, $contract_months, $description]);
|
||||||
|
}
|
||||||
|
|
||||||
|
header('Location: plans.php');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
<h1><?php echo $page_title; ?></h1>
|
||||||
|
|
||||||
|
<form action="plan_edit.php<?php echo isset($plan['id']) && $plan['id'] ? '?id='.$plan['id'] : '' ?>" method="post">
|
||||||
|
<?php if (isset($plan['id']) && $plan['id']): ?>
|
||||||
|
<input type="hidden" name="id" value="<?php echo htmlspecialchars($plan['id']); ?>">
|
||||||
|
<?php endif; ?>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="name" class="form-label">Plan Name</label>
|
||||||
|
<input type="text" class="form-control" id="name" name="name" value="<?php echo htmlspecialchars($plan['name']); ?>" required>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="speed_mbps" class="form-label">Speed (Mbps)</label>
|
||||||
|
<input type="number" class="form-control" id="speed_mbps" name="speed_mbps" value="<?php echo htmlspecialchars($plan['speed_mbps']); ?>" required>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="price_monthly" class="form-label">Price (Monthly)</label>
|
||||||
|
<input type="number" step="0.01" class="form-control" id="price_monthly" name="price_monthly" value="<?php echo htmlspecialchars($plan['price_monthly']); ?>" required>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="contract_months" class="form-label">Contract (Months)</label>
|
||||||
|
<input type="number" class="form-control" id="contract_months" name="contract_months" value="<?php echo htmlspecialchars($plan['contract_months']); ?>" required>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="description" class="form-label">Description</label>
|
||||||
|
<textarea class="form-control" id="description" name="description" rows="3"><?php echo htmlspecialchars($plan['description']); ?></textarea>
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="btn btn-primary">Save Plan</button>
|
||||||
|
<a href="plans.php" class="btn btn-secondary">Cancel</a>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<?php include 'footer.php'; ?>
|
||||||
49
admin/plans.php
Normal file
49
admin/plans.php
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
<?php
|
||||||
|
include __DIR__ . '/../db/config.php';
|
||||||
|
include 'header.php';
|
||||||
|
|
||||||
|
$pdo = db();
|
||||||
|
$stmt = $pdo->query('SELECT * FROM plans ORDER BY price_monthly');
|
||||||
|
$plans = $stmt->fetchAll();
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||||
|
<h1>Internet Plans</h1>
|
||||||
|
<a href="plan_edit.php" class="btn btn-success">Add New Plan</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<table class="table table-striped table-bordered">
|
||||||
|
<thead class="table-dark">
|
||||||
|
<tr>
|
||||||
|
<th>ID</th>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Speed</th>
|
||||||
|
<th>Price (Monthly)</th>
|
||||||
|
<th>Contract Length</th>
|
||||||
|
<th>Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<?php if (empty($plans)): ?>
|
||||||
|
<tr>
|
||||||
|
<td colspan="6" class="text-center">No plans found.</td>
|
||||||
|
</tr>
|
||||||
|
<?php else: ?>
|
||||||
|
<?php foreach ($plans as $plan): ?>
|
||||||
|
<tr>
|
||||||
|
<td><?php echo htmlspecialchars($plan['id']); ?></td>
|
||||||
|
<td><?php echo htmlspecialchars($plan['name']); ?></td>
|
||||||
|
<td><?php echo htmlspecialchars($plan['speed_mbps']); ?> Mbps</td>
|
||||||
|
<td>$<?php echo htmlspecialchars(number_format($plan['price_monthly'], 2)); ?></td>
|
||||||
|
<td><?php echo htmlspecialchars($plan['contract_months']); ?> months</td>
|
||||||
|
<td>
|
||||||
|
<a href="plan_edit.php?id=<?php echo $plan['id']; ?>" class="btn btn-sm btn-primary">Edit</a>
|
||||||
|
<a href="plan_delete.php?id=<?php echo $plan['id']; ?>" class="btn btn-sm btn-danger" onclick="return confirm('Are you sure?');">Delete</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
<?php endif; ?>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<?php include 'footer.php'; ?>
|
||||||
75
api/ai_support.php
Normal file
75
api/ai_support.php
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
<?php
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
|
||||||
|
require_once __DIR__ . '/../db/config.php';
|
||||||
|
|
||||||
|
// 1. Fetch plans from the database to create a knowledge base.
|
||||||
|
$knowledge_base = "";
|
||||||
|
try {
|
||||||
|
$pdo = db();
|
||||||
|
$stmt = $pdo->query("SELECT name, speed_mbps, price_monthly, contract_length_months FROM plans ORDER BY price_monthly ASC");
|
||||||
|
$plans = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
|
if ($plans) {
|
||||||
|
$knowledge_base .= "Here is a list of our current internet plans:\n\n";
|
||||||
|
foreach ($plans as $plan) {
|
||||||
|
$knowledge_base .= "- Plan Name: " . $plan['name'] . "\n";
|
||||||
|
$knowledge_base .= " - Speed: " . $plan['speed_mbps'] . " Mbps\n";
|
||||||
|
$knowledge_base .= " - Price: $" . $plan['price_monthly'] . " per month\n";
|
||||||
|
$knowledge_base .= " - Contract: " . $plan['contract_length_months'] . " months\n\n";
|
||||||
|
}
|
||||||
|
$knowledge_base .= "You are a helpful and friendly customer support assistant for a telecommunications company. Your goal is to answer customer questions based ONLY on the information provided in this knowledge base. Do not invent or assume any details. If the answer is not in the knowledge base, say 'I'm sorry, I don't have that information, but I can connect you with a human agent.' Keep your answers concise and to the point.";
|
||||||
|
}
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
// In a real app, you'd log this error.
|
||||||
|
// For now, we'll proceed with an empty knowledge base on failure.
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Get the user's question
|
||||||
|
$data = json_decode(file_get_contents('php://input'), true);
|
||||||
|
$user_question = $data['question'] ?? '';
|
||||||
|
|
||||||
|
if (empty($user_question)) {
|
||||||
|
echo json_encode(['error' => 'No question provided.']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Prepare the data for the Gemini API
|
||||||
|
// IMPORTANT: You must replace getenv('GEMINI_API_KEY') with your actual API key.
|
||||||
|
$api_key = getenv('GEMINI_API_KEY');
|
||||||
|
$api_url = 'https://generativelanguage.googleapis.com/v1beta/models/gemini-pro:generateContent?key=' . $api_key;
|
||||||
|
|
||||||
|
$payload = [
|
||||||
|
'contents' => [
|
||||||
|
[
|
||||||
|
'parts' => [
|
||||||
|
['text' => $knowledge_base . "\n\nCustomer Question: " . $user_question]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
// 4. Use cURL to make the API call
|
||||||
|
$ch = curl_init();
|
||||||
|
curl_setopt($ch, CURLOPT_URL, $api_url);
|
||||||
|
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
|
||||||
|
curl_setopt($ch, CURLOPT_POST, true);
|
||||||
|
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
|
||||||
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||||
|
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // For local development only
|
||||||
|
|
||||||
|
$response = curl_exec($ch);
|
||||||
|
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||||
|
curl_close($ch);
|
||||||
|
|
||||||
|
// 5. Process and return the response
|
||||||
|
if ($http_code === 200) {
|
||||||
|
$result = json_decode($response, true);
|
||||||
|
$ai_response = $result['candidates'][0]['content']['parts'][0]['text'] ?? 'I am unable to answer at this time.';
|
||||||
|
echo json_encode(['reply' => $ai_response]);
|
||||||
|
} else {
|
||||||
|
// Log the error response for debugging
|
||||||
|
error_log("Gemini API Error: HTTP " . $http_code . " - " . $response);
|
||||||
|
echo json_encode(['error' => 'Failed to get a response from the AI assistant. Please try again later.']);
|
||||||
|
}
|
||||||
|
|
||||||
54
api/check_availability.php
Normal file
54
api/check_availability.php
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
<?php
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
|
||||||
|
require_once __DIR__ . '/../db/config.php';
|
||||||
|
|
||||||
|
$response = [
|
||||||
|
'success' => false,
|
||||||
|
'message' => 'An error occurred.',
|
||||||
|
'serviceable' => false
|
||||||
|
];
|
||||||
|
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||||
|
$response['message'] = 'Invalid request method.';
|
||||||
|
echo json_encode($response);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$input = json_decode(file_get_contents('php://input'), true);
|
||||||
|
$address = $input['address'] ?? '';
|
||||||
|
|
||||||
|
if (empty($address)) {
|
||||||
|
$response['message'] = 'Address cannot be empty.';
|
||||||
|
echo json_encode($response);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is a very simple search. A real-world application would need a more robust
|
||||||
|
// address parsing and matching engine (e.g., using Google Geocoding API and spatial data).
|
||||||
|
// For this demo, we'll just do a broad search on the input string.
|
||||||
|
|
||||||
|
try {
|
||||||
|
$pdo = db();
|
||||||
|
$stmt = $pdo->prepare(
|
||||||
|
"SELECT COUNT(*) FROM serviceable_addresses WHERE CONCAT_WS(' ', street, suburb, state, postcode) LIKE ?"
|
||||||
|
);
|
||||||
|
$stmt->execute(['%' . $address . '%']);
|
||||||
|
$count = $stmt->fetchColumn();
|
||||||
|
|
||||||
|
if ($count > 0) {
|
||||||
|
$response['serviceable'] = true;
|
||||||
|
$response['message'] = 'Great news! Your address is serviceable.';
|
||||||
|
} else {
|
||||||
|
$response['serviceable'] = false;
|
||||||
|
$response['message'] = "Sorry, we don't seem to be in your area yet. Please contact us for more information.";
|
||||||
|
}
|
||||||
|
$response['success'] = true;
|
||||||
|
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
// In a real app, you would log this error, not expose it to the user.
|
||||||
|
$response['message'] = 'Database error.'; // Generic message for the user
|
||||||
|
// error_log($e->getMessage()); // Example of logging
|
||||||
|
}
|
||||||
|
|
||||||
|
echo json_encode($response);
|
||||||
55
api/create_payment_intent.php
Normal file
55
api/create_payment_intent.php
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
<?php
|
||||||
|
require_once __DIR__ . '/../vendor/autoload.php';
|
||||||
|
require_once __DIR__ . '/../db/config.php';
|
||||||
|
|
||||||
|
// This is your test secret API key. Don't hardcode this in a real app.
|
||||||
|
\Stripe\Stripe::setApiKey('sk_test_51Hh9Y2L9s5P2Q8Z4sYgY8Z4sYgY8Z4sYgY8Z4sYgY8Z4sYgY8Z4sYgY8Z4sYgY8Z4sYgY8Z4sYgY8Z4');
|
||||||
|
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
|
||||||
|
function calculateOrderAmount(object $plan): int {
|
||||||
|
// Calculate 10% GST
|
||||||
|
$gst = $plan->price_monthly * 0.10;
|
||||||
|
$total = $plan->price_monthly + $gst;
|
||||||
|
// Return amount in cents
|
||||||
|
return round($total * 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$json_str = file_get_contents('php://input');
|
||||||
|
$json_obj = json_decode($json_str);
|
||||||
|
|
||||||
|
if (!isset($json_obj->plan_id)) {
|
||||||
|
throw new Exception("Plan ID not provided.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$pdo = db();
|
||||||
|
$stmt = $pdo->prepare("SELECT * FROM plans WHERE id = ? AND is_active = 1");
|
||||||
|
$stmt->execute([$json_obj->plan_id]);
|
||||||
|
$plan = $stmt->fetch(PDO::FETCH_OBJ);
|
||||||
|
|
||||||
|
if (!$plan) {
|
||||||
|
throw new Exception("Plan not found.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$paymentIntent = \Stripe\PaymentIntent::create([
|
||||||
|
'amount' => calculateOrderAmount($plan),
|
||||||
|
'currency' => 'aud',
|
||||||
|
'automatic_payment_methods' => [
|
||||||
|
'enabled' => true,
|
||||||
|
],
|
||||||
|
'metadata' => [
|
||||||
|
'plan_id' => $plan->id
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
echo json_encode([
|
||||||
|
'clientSecret' => $paymentIntent->client_secret,
|
||||||
|
]);
|
||||||
|
} catch (Error $e) {
|
||||||
|
http_response_code(500);
|
||||||
|
echo json_encode(['error' => $e->getMessage()]);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
http_response_code(400);
|
||||||
|
echo json_encode(['error' => $e->getMessage()]);
|
||||||
|
}
|
||||||
76
api/process_signup.php
Normal file
76
api/process_signup.php
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
<?php
|
||||||
|
require_once __DIR__ . '/../vendor/autoload.php';
|
||||||
|
require_once __DIR__ . '/../db/config.php';
|
||||||
|
|
||||||
|
\Stripe\Stripe::setApiKey('sk_test_51Hh9Y2L9s5P2Q8Z4sYgY8Z4sYgY8Z4sYgY8Z4sYgY8Z4sYgY8Z4sYgY8Z4sYgY8Z4sYgY8Z4sYgY8Z4');
|
||||||
|
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
|
||||||
|
$json_str = file_get_contents('php://input');
|
||||||
|
$json_obj = json_decode($json_str);
|
||||||
|
|
||||||
|
$pdo = db();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 1. Validation
|
||||||
|
if (empty($json_obj->plan_id) || empty($json_obj->name) || empty($json_obj->email) || empty($json_obj->address) || empty($json_obj->password)) {
|
||||||
|
throw new Exception('Incomplete data provided.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Fetch Plan
|
||||||
|
$stmt = $pdo->prepare("SELECT * FROM plans WHERE id = ?");
|
||||||
|
$stmt->execute([$json_obj->plan_id]);
|
||||||
|
$plan = $stmt->fetch(PDO::FETCH_OBJ);
|
||||||
|
if (!$plan) {
|
||||||
|
throw new Exception('Plan not found.');
|
||||||
|
}
|
||||||
|
$order_amount = $plan->price_monthly; // Amount in dollars
|
||||||
|
|
||||||
|
// 3. Create Stripe Customer
|
||||||
|
$stripe_customer = \Stripe\Customer::create([
|
||||||
|
'name' => $json_obj->name,
|
||||||
|
'email' => $json_obj->email,
|
||||||
|
'address' => [
|
||||||
|
'line1' => $json_obj->address
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 4. Create Local Customer
|
||||||
|
$hashed_password = password_hash($json_obj->password, PASSWORD_DEFAULT);
|
||||||
|
$stmt = $pdo->prepare("INSERT INTO customers (name, email, password, service_address, stripe_customer_id) VALUES (?, ?, ?, ?, ?)");
|
||||||
|
$stmt->execute([$json_obj->name, $json_obj->email, $hashed_password, $json_obj->address, $stripe_customer->id]);
|
||||||
|
$customer_id = $pdo->lastInsertId();
|
||||||
|
|
||||||
|
// 5. Create Local Order
|
||||||
|
$stmt = $pdo->prepare("INSERT INTO orders (customer_id, plan_id, order_status, amount) VALUES (?, ?, 'pending', ?)");
|
||||||
|
$stmt->execute([$customer_id, $plan->id, $order_amount]);
|
||||||
|
$order_id = $pdo->lastInsertId();
|
||||||
|
|
||||||
|
// 6. Create Stripe Payment Intent
|
||||||
|
$paymentIntent = \Stripe\PaymentIntent::create([
|
||||||
|
'customer' => $stripe_customer->id,
|
||||||
|
'amount' => round($order_amount * 100), // Amount in cents
|
||||||
|
'currency' => 'aud',
|
||||||
|
'automatic_payment_methods' => [
|
||||||
|
'enabled' => true,
|
||||||
|
],
|
||||||
|
'metadata' => [
|
||||||
|
'order_id' => $order_id,
|
||||||
|
'customer_id' => $customer_id,
|
||||||
|
'plan_id' => $plan->id
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 7. Update Local Order with Payment Intent ID
|
||||||
|
$stmt = $pdo->prepare("UPDATE orders SET stripe_payment_intent_id = ? WHERE id = ?");
|
||||||
|
$stmt->execute([$paymentIntent->id, $order_id]);
|
||||||
|
|
||||||
|
// 8. Return Client Secret
|
||||||
|
echo json_encode([
|
||||||
|
'clientSecret' => $paymentIntent->client_secret,
|
||||||
|
]);
|
||||||
|
|
||||||
|
} catch (Exception $e) {
|
||||||
|
http_response_code(500);
|
||||||
|
echo json_encode(['error' => $e->getMessage()]);
|
||||||
|
}
|
||||||
32
api/update_payment_intent.php
Normal file
32
api/update_payment_intent.php
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
require_once __DIR__ . '/../vendor/autoload.php';
|
||||||
|
|
||||||
|
\Stripe\Stripe::setApiKey('sk_test_51Hh9Y2L9s5P2Q8Z4sYgY8Z4sYgY8Z4sYgY8Z4sYgY8Z4sYgY8Z4sYgY8Z4sYgY8Z4sYgY8Z4sYgY8Z4');
|
||||||
|
|
||||||
|
header('Content-Type: application/json');
|
||||||
|
|
||||||
|
try {
|
||||||
|
$json_str = file_get_contents('php://input');
|
||||||
|
$json_obj = json_decode($json_str);
|
||||||
|
|
||||||
|
if (empty($json_obj->payment_intent_id) || empty($json_obj->name) || empty($json_obj->email) || empty($json_obj->address)) {
|
||||||
|
throw new Exception("Missing required parameters.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$paymentIntent = \Stripe\PaymentIntent::update(
|
||||||
|
$json_obj->payment_intent_id,
|
||||||
|
[
|
||||||
|
'receipt_email' => $json_obj->email,
|
||||||
|
'metadata' => [
|
||||||
|
'customer_name' => $json_obj->name,
|
||||||
|
'customer_address' => $json_obj->address
|
||||||
|
]
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
echo json_encode(['status' => 'success']);
|
||||||
|
|
||||||
|
} catch (Exception $e) {
|
||||||
|
http_response_code(400);
|
||||||
|
echo json_encode(['error' => $e->getMessage()]);
|
||||||
|
}
|
||||||
111
assets/css/custom.css
Normal file
111
assets/css/custom.css
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
/* General Styles */
|
||||||
|
body {
|
||||||
|
font-family: 'Poppins', sans-serif;
|
||||||
|
padding-top: 56px; /* Adjust for fixed navbar */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Header */
|
||||||
|
.navbar-brand {
|
||||||
|
font-weight: 700;
|
||||||
|
color: #007BFF !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hero Section */
|
||||||
|
.hero {
|
||||||
|
background: linear-gradient(45deg, #007BFF, #00C6FF);
|
||||||
|
color: white;
|
||||||
|
padding: 120px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero h1 {
|
||||||
|
font-size: 3.5rem;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero .lead {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero .input-group {
|
||||||
|
box-shadow: 0 10px 30px rgba(0,0,0,0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero .form-control {
|
||||||
|
border-top-left-radius: 0.5rem;
|
||||||
|
border-bottom-left-radius: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hero .btn {
|
||||||
|
border-top-right-radius: 0.5rem;
|
||||||
|
border-bottom-right-radius: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Plans Section */
|
||||||
|
#plans {
|
||||||
|
background-color: #F8F9FA;
|
||||||
|
}
|
||||||
|
|
||||||
|
.plan-card {
|
||||||
|
background: #FFFFFF;
|
||||||
|
border: 1px solid #e9ecef;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
padding: 2.5rem;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
transition: transform 0.3s, box-shadow 0.3s;
|
||||||
|
box-shadow: 0 4px 6px rgba(0,0,0,0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.plan-card:hover {
|
||||||
|
transform: translateY(-10px);
|
||||||
|
box-shadow: 0 15px 25px rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.plan-card h3 {
|
||||||
|
font-weight: 700;
|
||||||
|
color: #007BFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.plan-card .price {
|
||||||
|
font-size: 2.5rem;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.plan-card .period {
|
||||||
|
font-size: 1rem;
|
||||||
|
color: #6C757D;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Buttons */
|
||||||
|
.btn-primary {
|
||||||
|
background-color: #007BFF;
|
||||||
|
border-color: #007BFF;
|
||||||
|
padding: 0.75rem 1.5rem;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
font-weight: 700;
|
||||||
|
transition: background-color 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary:hover {
|
||||||
|
background-color: #0056b3;
|
||||||
|
border-color: #0056b3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-outline-primary {
|
||||||
|
border-color: #007BFF;
|
||||||
|
color: #007BFF;
|
||||||
|
padding: 0.75rem 1.5rem;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-outline-primary:hover {
|
||||||
|
background-color: #007BFF;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Footer */
|
||||||
|
footer a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
80
assets/js/main.js
Normal file
80
assets/js/main.js
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
// Smooth scrolling for anchor links
|
||||||
|
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
|
||||||
|
anchor.addEventListener('click', function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
document.querySelector(this.getAttribute('href')).scrollIntoView({
|
||||||
|
behavior: 'smooth'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Address Availability Check
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
const availabilityForm = document.getElementById('availability-form');
|
||||||
|
const availabilityResult = document.getElementById('availability-result');
|
||||||
|
|
||||||
|
if (availabilityForm) {
|
||||||
|
availabilityForm.addEventListener('submit', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
const addressInput = document.getElementById('address-input');
|
||||||
|
const address = addressInput.value;
|
||||||
|
const button = this.querySelector('button');
|
||||||
|
|
||||||
|
if (!address) {
|
||||||
|
availabilityResult.textContent = 'Please enter an address.';
|
||||||
|
availabilityResult.className = 'alert alert-warning';
|
||||||
|
availabilityResult.style.display = 'block';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show loading state
|
||||||
|
button.disabled = true;
|
||||||
|
button.textContent = 'Checking...';
|
||||||
|
availabilityResult.style.display = 'none';
|
||||||
|
|
||||||
|
fetch('api/check_availability.php', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ address: address })
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
if (data.success) {
|
||||||
|
if (data.serviceable) {
|
||||||
|
// Address is serviceable, scroll to plans section
|
||||||
|
document.getElementById('plans').scrollIntoView({
|
||||||
|
behavior: 'smooth'
|
||||||
|
});
|
||||||
|
// Optionally, hide the success message after a delay
|
||||||
|
setTimeout(() => {
|
||||||
|
availabilityResult.style.display = 'none';
|
||||||
|
}, 3000);
|
||||||
|
availabilityResult.textContent = data.message;
|
||||||
|
availabilityResult.className = 'alert alert-success';
|
||||||
|
} else {
|
||||||
|
// Address is not serviceable
|
||||||
|
availabilityResult.textContent = data.message;
|
||||||
|
availabilityResult.className = 'alert alert-info';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
availabilityResult.textContent = data.message || 'An unexpected error occurred.';
|
||||||
|
availabilityResult.className = 'alert alert-danger';
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.error('Error:', error);
|
||||||
|
availabilityResult.textContent = 'A network error occurred. Please try again.';
|
||||||
|
availabilityResult.className = 'alert alert-danger';
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
availabilityResult.style.display = 'block';
|
||||||
|
button.disabled = false;
|
||||||
|
button.textContent = 'Check Availability';
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
102
assets/js/signup.js
Normal file
102
assets/js/signup.js
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
const stripe = Stripe('pk_test_51Hh9Y2L9s5P2Q8Z4sYgY8Z4sYgY8Z4sYgY8Z4sYgY8Z4sYgY8Z4sYgY8Z4sYgY8Z4sYgY8Z4sYgY8Z4sYgY8Z4');
|
||||||
|
|
||||||
|
const form = document.querySelector("#signup-form");
|
||||||
|
form.addEventListener("submit", handleSubmit);
|
||||||
|
|
||||||
|
// Initially, disable the submit button until the form is filled
|
||||||
|
document.querySelector("#submit").disabled = true;
|
||||||
|
|
||||||
|
// Create and mount the Payment Element
|
||||||
|
const elements = stripe.elements();
|
||||||
|
const paymentElement = elements.create("payment");
|
||||||
|
paymentElement.mount("#payment-element");
|
||||||
|
|
||||||
|
// Re-enable the submit button when the Payment Element is ready
|
||||||
|
paymentElement.on('ready', () => {
|
||||||
|
document.querySelector("#submit").disabled = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
async function handleSubmit(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
setLoading(true);
|
||||||
|
|
||||||
|
const name = document.getElementById('name').value;
|
||||||
|
const email = document.getElementById('email').value;
|
||||||
|
const password = document.getElementById('password').value;
|
||||||
|
const passwordConfirm = document.getElementById('password_confirm').value;
|
||||||
|
const address = document.getElementById('address').value;
|
||||||
|
const planId = form.dataset.planId;
|
||||||
|
|
||||||
|
if (password !== passwordConfirm) {
|
||||||
|
showMessage("Passwords do not match.");
|
||||||
|
setLoading(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!name || !email || !address || !planId || !password) {
|
||||||
|
showMessage("Please fill out all fields.");
|
||||||
|
setLoading(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create customer, order, and payment intent on the server.
|
||||||
|
const response = await fetch("/api/process_signup.php", {
|
||||||
|
method: "POST",
|
||||||
|
headers: { "Content-Type": "application/json" },
|
||||||
|
body: JSON.stringify({
|
||||||
|
plan_id: planId,
|
||||||
|
name: name,
|
||||||
|
email: email,
|
||||||
|
password: password,
|
||||||
|
address: address
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
const { clientSecret, error } = await response.json();
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
showMessage(error);
|
||||||
|
setLoading(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Confirm the payment with the client secret.
|
||||||
|
const { error: stripeError } = await stripe.confirmPayment({
|
||||||
|
elements,
|
||||||
|
clientSecret,
|
||||||
|
confirmParams: {
|
||||||
|
return_url: window.location.origin + "/order_confirmation.php",
|
||||||
|
receipt_email: email,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (stripeError) {
|
||||||
|
showMessage(stripeError.message);
|
||||||
|
}
|
||||||
|
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------- UI helpers -------
|
||||||
|
function showMessage(messageText) {
|
||||||
|
const messageContainer = document.querySelector("#payment-message");
|
||||||
|
messageContainer.style.display = "block";
|
||||||
|
messageContainer.textContent = messageText;
|
||||||
|
setTimeout(function () {
|
||||||
|
messageContainer.style.display = "none";
|
||||||
|
messageContainer.textContent = "";
|
||||||
|
}, 5000);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setLoading(isLoading) {
|
||||||
|
if (isLoading) {
|
||||||
|
document.querySelector("#submit").disabled = true;
|
||||||
|
document.querySelector("#spinner").style.display = "inline";
|
||||||
|
document.querySelector("#button-text").style.display = "none";
|
||||||
|
} else {
|
||||||
|
document.querySelector("#submit").disabled = false;
|
||||||
|
document.querySelector("#spinner").style.display = "none";
|
||||||
|
document.querySelector("#button-text").style.display = "inline";
|
||||||
|
}
|
||||||
|
}
|
||||||
6
composer.json
Normal file
6
composer.json
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"name": "flatlogic/customer-project",
|
||||||
|
"require": {
|
||||||
|
"stripe/stripe-php": "^1.8"
|
||||||
|
}
|
||||||
|
}
|
||||||
69
composer.lock
generated
Normal file
69
composer.lock
generated
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
{
|
||||||
|
"_readme": [
|
||||||
|
"This file locks the dependencies of your project to a known state",
|
||||||
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
|
"This file is @generated automatically"
|
||||||
|
],
|
||||||
|
"content-hash": "9b60f1d4a7d471b52635c3ca8c3ea56e",
|
||||||
|
"packages": [
|
||||||
|
{
|
||||||
|
"name": "stripe/stripe-php",
|
||||||
|
"version": "v1.8.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/stripe/stripe-php.git",
|
||||||
|
"reference": "5eba614baf4adefffdd59d196679a16d7baf70da"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/stripe/stripe-php/zipball/5eba614baf4adefffdd59d196679a16d7baf70da",
|
||||||
|
"reference": "5eba614baf4adefffdd59d196679a16d7baf70da",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"ext-curl": "*",
|
||||||
|
"php": ">=5.2"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"vierbergenlars/simpletest": "*"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"classmap": [
|
||||||
|
"lib/Stripe/"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Stripe and contributors",
|
||||||
|
"homepage": "https://github.com/stripe/stripe-php/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Stripe PHP Library",
|
||||||
|
"homepage": "https://stripe.com/",
|
||||||
|
"keywords": [
|
||||||
|
"api",
|
||||||
|
"payment processing",
|
||||||
|
"stripe"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/stripe/stripe-php/issues",
|
||||||
|
"source": "https://github.com/stripe/stripe-php/tree/transfers-recipients"
|
||||||
|
},
|
||||||
|
"time": "2013-04-12T18:56:41+00:00"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"packages-dev": [],
|
||||||
|
"aliases": [],
|
||||||
|
"minimum-stability": "stable",
|
||||||
|
"stability-flags": {},
|
||||||
|
"prefer-stable": false,
|
||||||
|
"prefer-lowest": false,
|
||||||
|
"platform": {},
|
||||||
|
"platform-dev": {},
|
||||||
|
"plugin-api-version": "2.6.0"
|
||||||
|
}
|
||||||
BIN
composer.phar
Executable file
BIN
composer.phar
Executable file
Binary file not shown.
41
db/migrate.php
Normal file
41
db/migrate.php
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
<?php
|
||||||
|
// Simple migration runner
|
||||||
|
|
||||||
|
require_once __DIR__ . '/config.php';
|
||||||
|
|
||||||
|
// 1. Connect without a database selected to create it
|
||||||
|
try {
|
||||||
|
$pdo_admin = new PDO('mysql:host='.DB_HOST, DB_USER, DB_PASS, [
|
||||||
|
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||||
|
]);
|
||||||
|
$pdo_admin->exec("CREATE DATABASE IF NOT EXISTS `".DB_NAME."`");
|
||||||
|
echo "Database `".DB_NAME."` created or already exists.\n";
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
echo "Error creating database: " . $e->getMessage() . "\n";
|
||||||
|
// If we can't create the DB, we probably can't do anything else.
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 2. Now connect to the database and run migrations
|
||||||
|
$pdo = db();
|
||||||
|
|
||||||
|
$migrations_dir = __DIR__ . '/migrations';
|
||||||
|
$files = glob($migrations_dir . '/*.sql');
|
||||||
|
|
||||||
|
sort($files);
|
||||||
|
|
||||||
|
foreach ($files as $file) {
|
||||||
|
echo "Running migration: " . basename($file) . "\n";
|
||||||
|
try {
|
||||||
|
$sql = file_get_contents($file);
|
||||||
|
$pdo->exec($sql);
|
||||||
|
echo "Success.\n";
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
echo "Error: " . $e->getMessage() . "\n";
|
||||||
|
// Continue on error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "All migrations completed.\n";
|
||||||
|
?>
|
||||||
17
db/migrations/001_create_serviceable_addresses.sql
Normal file
17
db/migrations/001_create_serviceable_addresses.sql
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
-- Create the table for serviceable addresses
|
||||||
|
CREATE TABLE IF NOT EXISTS `serviceable_addresses` (
|
||||||
|
`id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
`street` VARCHAR(255) NOT NULL,
|
||||||
|
`suburb` VARCHAR(255) NOT NULL,
|
||||||
|
`postcode` VARCHAR(10) NOT NULL,
|
||||||
|
`state` VARCHAR(10) NOT NULL,
|
||||||
|
INDEX `idx_address` (`street`, `suburb`, `postcode`, `state`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
|
|
||||||
|
-- Insert some sample data for testing
|
||||||
|
INSERT INTO `serviceable_addresses` (`street`, `suburb`, `postcode`, `state`) VALUES
|
||||||
|
('123 Fake St', 'Sydney', '2000', 'NSW'),
|
||||||
|
('456 Example Ave', 'Melbourne', '3000', 'VIC'),
|
||||||
|
('789 Sample Rd', 'Brisbane', '4000', 'QLD'),
|
||||||
|
('101 Test St', 'Perth', '6000', 'WA'),
|
||||||
|
('222 Demo Dr', 'Adelaide', '5000', 'SA');
|
||||||
10
db/migrations/002_create_plans_table.sql
Normal file
10
db/migrations/002_create_plans_table.sql
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
-- Create the plans table
|
||||||
|
CREATE TABLE IF NOT EXISTS `plans` (
|
||||||
|
`id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
`name` VARCHAR(255) NOT NULL UNIQUE,
|
||||||
|
`speed_mbps` INT NOT NULL,
|
||||||
|
`price_monthly` DECIMAL(10, 2) NOT NULL,
|
||||||
|
`contract_months` INT NOT NULL,
|
||||||
|
`description` TEXT,
|
||||||
|
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
14
db/migrations/003_create_customers_table.sql
Normal file
14
db/migrations/003_create_customers_table.sql
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
-- Create the customers table
|
||||||
|
CREATE TABLE IF NOT EXISTS `customers` (
|
||||||
|
`id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
`first_name` VARCHAR(100) NOT NULL,
|
||||||
|
`last_name` VARCHAR(100) NOT NULL,
|
||||||
|
`email` VARCHAR(255) NOT NULL UNIQUE,
|
||||||
|
`phone` VARCHAR(50) NULL,
|
||||||
|
`password_hash` VARCHAR(255) NOT NULL, -- For storing hashed passwords
|
||||||
|
`street_address` VARCHAR(255) NULL,
|
||||||
|
`suburb` VARCHAR(100) NULL,
|
||||||
|
`state` VARCHAR(50) NULL,
|
||||||
|
`postcode` VARCHAR(20) NULL,
|
||||||
|
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
13
db/migrations/004_create_orders_table.sql
Normal file
13
db/migrations/004_create_orders_table.sql
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
-- Create the orders table
|
||||||
|
CREATE TABLE IF NOT EXISTS `orders` (
|
||||||
|
`id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
`customer_id` INT NOT NULL,
|
||||||
|
`plan_id` INT NOT NULL,
|
||||||
|
`order_status` VARCHAR(50) NOT NULL DEFAULT 'pending', -- e.g., pending, active, cancelled
|
||||||
|
`total_amount` DECIMAL(10, 2) NOT NULL,
|
||||||
|
`order_date` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
`activation_date` DATE NULL,
|
||||||
|
`notes` TEXT NULL,
|
||||||
|
FOREIGN KEY (`customer_id`) REFERENCES `customers`(`id`) ON DELETE CASCADE,
|
||||||
|
FOREIGN KEY (`plan_id`) REFERENCES `plans`(`id`) ON DELETE RESTRICT
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
7
db/migrations/005_create_pages_table.sql
Normal file
7
db/migrations/005_create_pages_table.sql
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
CREATE TABLE IF NOT EXISTS pages (
|
||||||
|
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||||
|
slug VARCHAR(255) NOT NULL UNIQUE,
|
||||||
|
title VARCHAR(255) NOT NULL,
|
||||||
|
content TEXT NOT NULL,
|
||||||
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
1
db/migrations/006_add_password_to_customers.sql
Normal file
1
db/migrations/006_add_password_to_customers.sql
Normal file
@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE `customers` ADD `password` VARCHAR(255) NOT NULL AFTER `email`;
|
||||||
12
db/migrations/007_seed_sample_data.sql
Normal file
12
db/migrations/007_seed_sample_data.sql
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
-- Seed the pages table with an "About Us" and "Terms of Service" page
|
||||||
|
INSERT INTO `pages` (`title`, `slug`, `content`) VALUES
|
||||||
|
('About Us', 'about-us', '<h1>About Us</h1><p>We are a leading provider of telecommunication services, committed to connecting you to the world. This page was generated by the CMS.</p>'),
|
||||||
|
('Terms of Service', 'terms-of-service', '<h1>Terms of Service</h1><p>By using our services, you agree to our terms. This is a sample page.</p>'),
|
||||||
|
('Privacy Policy', 'privacy-policy', '<h1>Privacy Policy</h1><p>Your privacy is important to us. This is a sample page.</p>');
|
||||||
|
|
||||||
|
-- Let's add some sample plans to make the landing page look populated.
|
||||||
|
INSERT INTO `plans` (`name`, `speed_mbps`, `price_monthly`, `contract_months`, `description`) VALUES
|
||||||
|
('Basic Connect', 25, 49.99, 12, 'Ideal for browsing and email.'),
|
||||||
|
('Family Streamer', 50, 69.99, 12, 'Perfect for streaming HD video on multiple devices.'),
|
||||||
|
('Super Fast Gamer', 100, 89.99, 24, 'Low latency for the ultimate gaming experience.'),
|
||||||
|
('Power User', 250, 109.99, 24, 'For heavy-duty usage, 4K streaming, and large downloads.');
|
||||||
47
footer.php
Normal file
47
footer.php
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
</main>
|
||||||
|
|
||||||
|
<footer class="py-4 bg-dark text-white">
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-4">
|
||||||
|
<h5>Quick Links</h5>
|
||||||
|
<ul class="list-unstyled">
|
||||||
|
<li><a href="index.php#hero" class="text-white">Home</a></li>
|
||||||
|
<li><a href="index.php#plans" class="text-white">Plans</a></li>
|
||||||
|
<li><a href="support.php" class="text-white">Support</a></li>
|
||||||
|
<li><a href="index.php#about" class="text-white">About</a></li>
|
||||||
|
<li><a href="index.php#contact" class="text-white">Contact</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<h5>Our Pages</h5>
|
||||||
|
<ul class="list-unstyled">
|
||||||
|
<?php
|
||||||
|
require_once __DIR__ . '/db/config.php';
|
||||||
|
try {
|
||||||
|
$pdo = db();
|
||||||
|
$stmt = $pdo->query("SELECT * FROM pages WHERE is_published = 1 ORDER BY title");
|
||||||
|
$pages = $stmt->fetchAll();
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
error_log($e->getMessage());
|
||||||
|
$pages = [];
|
||||||
|
}
|
||||||
|
foreach ($pages as $page) {
|
||||||
|
echo '<li><a href="page.php?slug=' . htmlspecialchars($page['slug']) . '" class="text-white">' . htmlspecialchars($page['title']) . '</a></li>';
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<h5>Connect</h5>
|
||||||
|
<p>© <?php echo date('Y'); ?> Australia Broadband Internet. All Rights Reserved.</p>
|
||||||
|
<p><a href="privacy.php" class="text-white">Privacy Policy</a></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
|
<script src="assets/js/main.js?v=<?php echo time(); ?>"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
45
header.php
Normal file
45
header.php
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
<?php session_start(); ?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Australia Broadband Internet</title>
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
|
||||||
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;700&display=swap" rel="stylesheet">
|
||||||
|
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<header class="navbar navbar-expand-lg navbar-light bg-light fixed-top">
|
||||||
|
<div class="container">
|
||||||
|
<a class="navbar-brand" href="index.php">ABI</a>
|
||||||
|
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
|
||||||
|
<span class="navbar-toggler-icon"></span>
|
||||||
|
</button>
|
||||||
|
<div class="collapse navbar-collapse" id="navbarNav">
|
||||||
|
<ul class="navbar-nav ms-auto">
|
||||||
|
<li class="nav-item"><a class="nav-link" href="index.php#hero">Home</a></li>
|
||||||
|
<li class="nav-item"><a class="nav-link" href="index.php#plans">Plans</a></li>
|
||||||
|
<li class="nav-item"><a class="nav-link" href="support.php">Support</a></li>
|
||||||
|
<li class="nav-item"><a class="nav-link" href="index.php#about">About</a></li>
|
||||||
|
<li class="nav-item"><a class="nav-link" href="index.php#contact">Contact</a></li>
|
||||||
|
<?php if (isset($_SESSION['user_id'])): // Admin user ?>
|
||||||
|
<li class="nav-item"><a class="nav-link" href="/admin">Admin</a></li>
|
||||||
|
<li class="nav-item"><a class="nav-link" href="/admin/logout.php">Logout</a></li>
|
||||||
|
<?php elseif (isset($_SESSION['customer_id'])): // Customer ?>
|
||||||
|
<li class="nav-item"><a class="nav-link" href="portal.php">My Portal</a></li>
|
||||||
|
<li class="nav-item"><a class="nav-link" href="logout.php">Logout</a></li>
|
||||||
|
<?php else: // Guest ?>
|
||||||
|
<li class="nav-item"><a class="nav-link" href="login.php">Login</a></li>
|
||||||
|
<?php endif; ?>
|
||||||
|
<li class="nav-item"><a class="btn btn-primary ms-lg-3" href="index.php#hero">Check Availability</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<main class="py-5 mt-5">
|
||||||
225
index.php
225
index.php
@ -1,150 +1,85 @@
|
|||||||
<?php
|
<?php include 'header.php'; ?>
|
||||||
declare(strict_types=1);
|
<section id="hero" class="hero text-center">
|
||||||
@ini_set('display_errors', '1');
|
<div class="container">
|
||||||
@error_reporting(E_ALL);
|
<h1>Fast, Reliable Internet for Your Home</h1>
|
||||||
@date_default_timezone_set('UTC');
|
<p class="lead">Check if Australia Broadband Internet is available at your address.</p>
|
||||||
|
<div class="row justify-content-center">
|
||||||
|
<div class="col-md-8">
|
||||||
|
<form id="availability-form">
|
||||||
|
<div class="input-group input-group-lg">
|
||||||
|
<input type="text" id="address-input" class="form-control" placeholder="Enter your street address, suburb and postcode...">
|
||||||
|
<button class="btn btn-primary" type="submit">Check Now</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
<div id="availability-result" class="mt-3" style="display: none;"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
$phpVersion = PHP_VERSION;
|
<section id="plans" class="py-5 bg-light">
|
||||||
$now = date('Y-m-d H:i:s');
|
<div class="container">
|
||||||
?>
|
<h2 class="text-center mb-5">Our Plans</h2>
|
||||||
<!doctype html>
|
<div class="row">
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
||||||
<title>New Style</title>
|
|
||||||
<?php
|
<?php
|
||||||
// Read project preview data from environment
|
require_once __DIR__ . '/db/config.php';
|
||||||
$projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? '';
|
try {
|
||||||
$projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? '';
|
$pdo = db();
|
||||||
|
$stmt = $pdo->query("SELECT * FROM plans ORDER BY price_monthly");
|
||||||
|
$plans = $stmt->fetchAll();
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
error_log($e->getMessage());
|
||||||
|
$plans = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($plans)):
|
||||||
?>
|
?>
|
||||||
<?php if ($projectDescription): ?>
|
<div class="col-12 text-center">
|
||||||
<!-- Meta description -->
|
<p>No plans available at the moment. Please check back later.</p>
|
||||||
<meta name="description" content='<?= htmlspecialchars($projectDescription) ?>' />
|
|
||||||
<!-- Open Graph meta tags -->
|
|
||||||
<meta property="og:description" content="<?= htmlspecialchars($projectDescription) ?>" />
|
|
||||||
<!-- Twitter meta tags -->
|
|
||||||
<meta property="twitter:description" content="<?= htmlspecialchars($projectDescription) ?>" />
|
|
||||||
<?php endif; ?>
|
|
||||||
<?php if ($projectImageUrl): ?>
|
|
||||||
<!-- Open Graph image -->
|
|
||||||
<meta property="og:image" content="<?= htmlspecialchars($projectImageUrl) ?>" />
|
|
||||||
<!-- Twitter image -->
|
|
||||||
<meta property="twitter:image" content="<?= htmlspecialchars($projectImageUrl) ?>" />
|
|
||||||
<?php endif; ?>
|
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap" rel="stylesheet">
|
|
||||||
<style>
|
|
||||||
:root {
|
|
||||||
--bg-color-start: #6a11cb;
|
|
||||||
--bg-color-end: #2575fc;
|
|
||||||
--text-color: #ffffff;
|
|
||||||
--card-bg-color: rgba(255, 255, 255, 0.01);
|
|
||||||
--card-border-color: rgba(255, 255, 255, 0.1);
|
|
||||||
}
|
|
||||||
body {
|
|
||||||
margin: 0;
|
|
||||||
font-family: 'Inter', sans-serif;
|
|
||||||
background: linear-gradient(45deg, var(--bg-color-start), var(--bg-color-end));
|
|
||||||
color: var(--text-color);
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
min-height: 100vh;
|
|
||||||
text-align: center;
|
|
||||||
overflow: hidden;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
body::before {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100"><path d="M-10 10L110 10M10 -10L10 110" stroke-width="1" stroke="rgba(255,255,255,0.05)"/></svg>');
|
|
||||||
animation: bg-pan 20s linear infinite;
|
|
||||||
z-index: -1;
|
|
||||||
}
|
|
||||||
@keyframes bg-pan {
|
|
||||||
0% { background-position: 0% 0%; }
|
|
||||||
100% { background-position: 100% 100%; }
|
|
||||||
}
|
|
||||||
main {
|
|
||||||
padding: 2rem;
|
|
||||||
}
|
|
||||||
.card {
|
|
||||||
background: var(--card-bg-color);
|
|
||||||
border: 1px solid var(--card-border-color);
|
|
||||||
border-radius: 16px;
|
|
||||||
padding: 2rem;
|
|
||||||
backdrop-filter: blur(20px);
|
|
||||||
-webkit-backdrop-filter: blur(20px);
|
|
||||||
box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
|
||||||
.loader {
|
|
||||||
margin: 1.25rem auto 1.25rem;
|
|
||||||
width: 48px;
|
|
||||||
height: 48px;
|
|
||||||
border: 3px solid rgba(255, 255, 255, 0.25);
|
|
||||||
border-top-color: #fff;
|
|
||||||
border-radius: 50%;
|
|
||||||
animation: spin 1s linear infinite;
|
|
||||||
}
|
|
||||||
@keyframes spin {
|
|
||||||
from { transform: rotate(0deg); }
|
|
||||||
to { transform: rotate(360deg); }
|
|
||||||
}
|
|
||||||
.hint {
|
|
||||||
opacity: 0.9;
|
|
||||||
}
|
|
||||||
.sr-only {
|
|
||||||
position: absolute;
|
|
||||||
width: 1px; height: 1px;
|
|
||||||
padding: 0; margin: -1px;
|
|
||||||
overflow: hidden;
|
|
||||||
clip: rect(0, 0, 0, 0);
|
|
||||||
white-space: nowrap; border: 0;
|
|
||||||
}
|
|
||||||
h1 {
|
|
||||||
font-size: 3rem;
|
|
||||||
font-weight: 700;
|
|
||||||
margin: 0 0 1rem;
|
|
||||||
letter-spacing: -1px;
|
|
||||||
}
|
|
||||||
p {
|
|
||||||
margin: 0.5rem 0;
|
|
||||||
font-size: 1.1rem;
|
|
||||||
}
|
|
||||||
code {
|
|
||||||
background: rgba(0,0,0,0.2);
|
|
||||||
padding: 2px 6px;
|
|
||||||
border-radius: 4px;
|
|
||||||
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
|
||||||
}
|
|
||||||
footer {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 1rem;
|
|
||||||
font-size: 0.8rem;
|
|
||||||
opacity: 0.7;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<main>
|
|
||||||
<div class="card">
|
|
||||||
<h1>Analyzing your requirements and generating your website…</h1>
|
|
||||||
<div class="loader" role="status" aria-live="polite" aria-label="Applying initial changes">
|
|
||||||
<span class="sr-only">Loading…</span>
|
|
||||||
</div>
|
</div>
|
||||||
<p class="hint"><?= ($_SERVER['HTTP_HOST'] ?? '') === 'appwizzy.com' ? 'AppWizzy' : 'Flatlogic' ?> AI is collecting your requirements and applying the first changes.</p>
|
<?php else: ?>
|
||||||
<p class="hint">This page will update automatically as the plan is implemented.</p>
|
<?php foreach ($plans as $plan): ?>
|
||||||
<p>Runtime: PHP <code><?= htmlspecialchars($phpVersion) ?></code> — UTC <code><?= htmlspecialchars($now) ?></code></p>
|
<div class="col-md-4 mb-4">
|
||||||
|
<div class="card h-100 shadow-sm">
|
||||||
|
<div class="card-body d-flex flex-column">
|
||||||
|
<h5 class="card-title text-center"><?php echo htmlspecialchars($plan['name']); ?></h5>
|
||||||
|
<div class="text-center my-4">
|
||||||
|
<span class="display-4 fw-bold">$<?php echo htmlspecialchars(number_format($plan['price_monthly'], 2)); ?></span>
|
||||||
|
<span class="text-muted">/mo</span>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
<ul class="list-unstyled mb-4 text-center">
|
||||||
<footer>
|
<li class="mb-2"><i class="bi bi-speedometer2 me-2"></i>Up to <?php echo htmlspecialchars($plan['speed_mbps']); ?> Mbps</li>
|
||||||
Page updated: <?= htmlspecialchars($now) ?> (UTC)
|
<li class="mb-2"><i class="bi bi-card-text me-2"></i><?php echo htmlspecialchars($plan['description']); ?></li>
|
||||||
</footer>
|
<li class="mb-2"><i class="bi bi-calendar-check me-2"></i><?php echo htmlspecialchars($plan['contract_months']); ?> months contract</li>
|
||||||
</body>
|
</ul>
|
||||||
</html>
|
<div class="mt-auto">
|
||||||
|
<a href="signup.php?plan_id=<?php echo $plan['id']; ?>" class="btn btn-primary w-100">Sign Up Now</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section id="about" class="bg-light py-5">
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-8 mx-auto text-center">
|
||||||
|
<h2>About Us</h2>
|
||||||
|
<p class="lead">Australia Broadband Internet is a leading provider of high-speed internet services. We are dedicated to delivering reliable and affordable connectivity to homes across Australia.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section id="contact" class="py-5">
|
||||||
|
<div class="container text-center">
|
||||||
|
<h2>Contact Us</h2>
|
||||||
|
<p>Email: support@abinet.com.au</p>
|
||||||
|
<p>Phone: 1300 864 341</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<?php include 'footer.php'; ?>
|
||||||
54
login.php
Normal file
54
login.php
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
<?php
|
||||||
|
require_once __DIR__ . '/db/config.php';
|
||||||
|
include 'header.php';
|
||||||
|
|
||||||
|
$error_message = '';
|
||||||
|
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
|
||||||
|
if (empty($_POST['email']) || empty($_POST['password'])) {
|
||||||
|
$error_message = 'Please enter both email and password.';
|
||||||
|
} else {
|
||||||
|
$pdo = db();
|
||||||
|
$stmt = $pdo->prepare("SELECT * FROM customers WHERE email = ?");
|
||||||
|
$stmt->execute([$_POST['email']]);
|
||||||
|
$customer = $stmt->fetch();
|
||||||
|
|
||||||
|
if ($customer && password_verify($_POST['password'], $customer['password'])) {
|
||||||
|
$_SESSION['customer_id'] = $customer['id'];
|
||||||
|
$_SESSION['customer_name'] = $customer['name'];
|
||||||
|
header('Location: portal.php');
|
||||||
|
exit;
|
||||||
|
} else {
|
||||||
|
$error_message = 'Invalid email or password.';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div class="container mt-5">
|
||||||
|
<div class="row justify-content-center">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body">
|
||||||
|
<h1 class="card-title text-center mb-4">Customer Login</h1>
|
||||||
|
<?php if ($error_message): ?>
|
||||||
|
<div class="alert alert-danger"><?php echo $error_message; ?></div>
|
||||||
|
<?php endif; ?>
|
||||||
|
<form method="POST" action="login.php">
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="email" class="form-label">Email Address</label>
|
||||||
|
<input type="email" id="email" name="email" class="form-control" required>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="password" class="form-label">Password</label>
|
||||||
|
<input type="password" id="password" name="password" class="form-control" required>
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="btn btn-primary w-100">Login</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php include 'footer.php'; ?>
|
||||||
6
logout.php
Normal file
6
logout.php
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?php
|
||||||
|
session_start();
|
||||||
|
session_unset();
|
||||||
|
session_destroy();
|
||||||
|
header('Location: index.php');
|
||||||
|
exit;
|
||||||
116
order_confirmation.php
Normal file
116
order_confirmation.php
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
<?php
|
||||||
|
require_once __DIR__ . '/vendor/autoload.php';
|
||||||
|
require_once __DIR__ . '/db/config.php';
|
||||||
|
|
||||||
|
\Stripe\Stripe::setApiKey('sk_test_51Hh9Y2L9s5P2Q8Z4sYgY8Z4sYgY8Z4sYgY8Z4sYgY8Z4sYgY8Z4sYgY8Z4sYgY8Z4sYgY8Z4sYgY8Z4');
|
||||||
|
|
||||||
|
include 'header.php';
|
||||||
|
|
||||||
|
$message = '';
|
||||||
|
$order_details = null;
|
||||||
|
$error = false;
|
||||||
|
|
||||||
|
if (empty($_GET['payment_intent'])) {
|
||||||
|
$error = true;
|
||||||
|
$message = "No payment intent provided.";
|
||||||
|
} else {
|
||||||
|
$payment_intent_id = $_GET['payment_intent'];
|
||||||
|
$pdo = db();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 1. Verify Payment with Stripe
|
||||||
|
$paymentIntent = \Stripe\PaymentIntent::retrieve($payment_intent_id);
|
||||||
|
|
||||||
|
if ($paymentIntent->status == 'succeeded') {
|
||||||
|
// 2. Find Local Order
|
||||||
|
$stmt = $pdo->prepare("SELECT * FROM orders WHERE stripe_payment_intent_id = ?");
|
||||||
|
$stmt->execute([$payment_intent_id]);
|
||||||
|
$order = $stmt->fetch(PDO::FETCH_OBJ);
|
||||||
|
|
||||||
|
if ($order) {
|
||||||
|
// 3. Update Order Status (if it's still pending)
|
||||||
|
if ($order->order_status == 'pending') {
|
||||||
|
$update_stmt = $pdo->prepare("UPDATE orders SET order_status = 'completed' WHERE id = ?");
|
||||||
|
$update_stmt->execute([$order->id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Fetch Order Details for Display
|
||||||
|
$details_stmt = $pdo->prepare(
|
||||||
|
"SELECT o.id as order_id, o.amount, c.name as customer_name, c.email, p.name as plan_name
|
||||||
|
FROM orders o
|
||||||
|
JOIN customers c ON o.customer_id = c.id
|
||||||
|
JOIN plans p ON o.plan_id = p.id
|
||||||
|
WHERE o.id = ?"
|
||||||
|
);
|
||||||
|
$details_stmt->execute([$order->id]);
|
||||||
|
$order_details = $details_stmt->fetch(PDO::FETCH_OBJ);
|
||||||
|
|
||||||
|
$message = "Thank you for your order! Your payment was successful.";
|
||||||
|
|
||||||
|
// 5. Send Confirmation Email (optional, but good practice)
|
||||||
|
require_once __DIR__ . '/mail/MailService.php';
|
||||||
|
$subject = 'Your Australia Broadband Internet Order Confirmation';
|
||||||
|
$html_body = "<h1>Welcome, " . htmlspecialchars($order_details->customer_name) . "!</h1>"
|
||||||
|
. "<p>Thank you for your order. Your new internet service is being processed.</p>"
|
||||||
|
. "<p><strong>Order Details:</strong></p>"
|
||||||
|
. "<ul>"
|
||||||
|
. "<li><strong>Order ID:</strong> " . htmlspecialchars($order_details->order_id) . "</li>"
|
||||||
|
. "<li><strong>Plan:</strong> " . htmlspecialchars($order_details->plan_name) . "</li>"
|
||||||
|
. "<li><strong>Amount Paid:</strong> $" . htmlspecialchars(number_format($order_details->amount, 2)) . "</li>"
|
||||||
|
. "</ul>"
|
||||||
|
. "<p>You will receive further updates from us shortly.</p>";
|
||||||
|
MailService::sendMail($order_details->email, $subject, $html_body);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
$error = true;
|
||||||
|
// This is a critical error. Payment succeeded but we can't find the order.
|
||||||
|
error_log("CRITICAL: Payment succeeded for PI {$payment_intent_id} but no matching order found in DB.");
|
||||||
|
$message = "Your payment was successful, but we could not find your order. Please contact support immediately.";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$error = true;
|
||||||
|
$message = "Your payment was not successful. Please try again or contact support.";
|
||||||
|
}
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$error = true;
|
||||||
|
error_log("Order confirmation error: " . $e->getMessage());
|
||||||
|
$message = "An error occurred while processing your order. Please contact support.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div class="container mt-5">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-8 offset-md-2 text-center">
|
||||||
|
<?php if ($error): ?>
|
||||||
|
<div class="alert alert-danger">
|
||||||
|
<h1 class="alert-heading">Order Error</h1>
|
||||||
|
<p><?php echo htmlspecialchars($message); ?></p>
|
||||||
|
</div>
|
||||||
|
<?php else: ?>
|
||||||
|
<div class="alert alert-success">
|
||||||
|
<h1 class="alert-heading">Thank You!</h1>
|
||||||
|
<p><?php echo htmlspecialchars($message); ?></p>
|
||||||
|
</div>
|
||||||
|
<?php if ($order_details): ?>
|
||||||
|
<div class="card mt-4">
|
||||||
|
<div class="card-header">
|
||||||
|
Order Summary
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<p><strong>Order ID:</strong> <?php echo htmlspecialchars($order_details->order_id); ?></p>
|
||||||
|
<p><strong>Customer:</strong> <?php echo htmlspecialchars($order_details->customer_name); ?></p>
|
||||||
|
<p><strong>Plan:</strong> <?php echo htmlspecialchars($order_details->plan_name); ?></p>
|
||||||
|
<p><strong>Amount Paid:</strong> $<?php echo htmlspecialchars(number_format($order_details->amount, 2)); ?></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php endif; ?>
|
||||||
|
<?php endif; ?>
|
||||||
|
<a href="/" class="btn btn-primary mt-4">Back to Home</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php
|
||||||
|
include 'footer.php';
|
||||||
|
?>
|
||||||
36
page.php
Normal file
36
page.php
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
<?php
|
||||||
|
require_once 'db/config.php';
|
||||||
|
|
||||||
|
$slug = $_GET['slug'] ?? null;
|
||||||
|
|
||||||
|
if (!$slug) {
|
||||||
|
http_response_code(404);
|
||||||
|
echo "Page not found.";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$stmt = db()->prepare('SELECT * FROM pages WHERE slug = ?');
|
||||||
|
$stmt->execute([$slug]);
|
||||||
|
$page = $stmt->fetch();
|
||||||
|
|
||||||
|
if (!$page) {
|
||||||
|
http_response_code(404);
|
||||||
|
echo "Page not found.";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
include 'header.php';
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div class="container mt-5 pt-5">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-10 mx-auto">
|
||||||
|
<h1 class="display-4 fw-bold text-center"><?php echo htmlspecialchars($page['title']); ?></h1>
|
||||||
|
<div class="mt-4 fs-5">
|
||||||
|
<?php echo nl2br(htmlspecialchars($page['content'])); ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php include 'footer.php'; ?>
|
||||||
26
portal.php
Normal file
26
portal.php
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
include 'header.php';
|
||||||
|
|
||||||
|
// Protect this page
|
||||||
|
if (!isset($_SESSION['customer_id'])) {
|
||||||
|
header('Location: login.php');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
|
||||||
|
<div class="container mt-5">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body">
|
||||||
|
<h1 class="card-title">Welcome, <?php echo htmlspecialchars($_SESSION['customer_name']); ?>!</h1>
|
||||||
|
<p>This is your customer portal. You can view your account details and manage your services here.</p>
|
||||||
|
<a href="logout.php" class="btn btn-primary">Logout</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php include 'footer.php'; ?>
|
||||||
20
privacy.php
Normal file
20
privacy.php
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
// privacy.php
|
||||||
|
?>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Privacy Policy - Australia Broadband</title>
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||||
|
<link rel="stylesheet" href="assets/css/custom.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container py-5">
|
||||||
|
<h1>Privacy Policy</h1>
|
||||||
|
<p>This is a placeholder for the Privacy Policy page.</p>
|
||||||
|
<a href="index.php">Back to Home</a>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
87
signup.php
Normal file
87
signup.php
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
<?php
|
||||||
|
require_once __DIR__ . '/db/config.php';
|
||||||
|
include 'header.php';
|
||||||
|
|
||||||
|
if (!isset($_GET['plan_id'])) {
|
||||||
|
header('Location: /#plans');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
$pdo = db();
|
||||||
|
$stmt = $pdo->prepare("SELECT * FROM plans WHERE id = ?");
|
||||||
|
$stmt->execute([$_GET['plan_id']]);
|
||||||
|
$plan = $stmt->fetch();
|
||||||
|
|
||||||
|
if (!$plan) {
|
||||||
|
// Plan not found
|
||||||
|
header('Location: /#plans');
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
?>
|
||||||
|
<div class="container mt-5">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-8 offset-md-2">
|
||||||
|
<h1 class="mb-4">Complete Your Order</h1>
|
||||||
|
|
||||||
|
<div class="card mb-4">
|
||||||
|
<div class="card-body">
|
||||||
|
<h4 class="card-title">Your Plan</h4>
|
||||||
|
<h5><?php echo htmlspecialchars($plan['name']); ?></h5>
|
||||||
|
<p class="price fs-4">$<?php echo htmlspecialchars(number_format($plan['price_monthly'], 2)); ?><span class="period">/mo</span></p>
|
||||||
|
<p><?php echo htmlspecialchars($plan['description']); ?></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h4 class="mb-3">Your Details</h4>
|
||||||
|
<form id="signup-form" data-plan-id="<?php echo $plan['id']; ?>">
|
||||||
|
<!-- User details form -->
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="name" class="form-label">Full Name</label>
|
||||||
|
<input type="text" id="name" class="form-control" required>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="email" class="form-label">Email Address</label>
|
||||||
|
<input type="email" id="email" class="form-control" required>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6 mb-3">
|
||||||
|
<label for="password" class="form-label">Password</label>
|
||||||
|
<input type="password" id="password" class="form-control" required>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6 mb-3">
|
||||||
|
<label for="password_confirm" class="form-label">Confirm Password</label>
|
||||||
|
<input type="password" id="password_confirm" class="form-control" required>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="address" class="form-label">Service Address</label>
|
||||||
|
<input type="text" id="address" class="form-control" required>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h4 class="mb-3 mt-4">Payment Details</h4>
|
||||||
|
<!-- Stripe Payment Element will go here -->
|
||||||
|
<div id="payment-element" class="mb-3"></div>
|
||||||
|
|
||||||
|
<!-- Used to display form errors -->
|
||||||
|
<div id="payment-message" class="hidden"></div>
|
||||||
|
|
||||||
|
<button id="submit" class="btn btn-primary btn-lg w-100">
|
||||||
|
<span id="button-text">Pay Now</span>
|
||||||
|
<span id="spinner" style="display: none;">Processing...</span>
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="https://js.stripe.com/v3/"></script>
|
||||||
|
<script>
|
||||||
|
// Pass plan details to JS
|
||||||
|
const planDetails = {
|
||||||
|
id: <?php echo json_encode($plan['id']); ?>,
|
||||||
|
price: <?php echo json_encode($plan['price_monthly']); ?>
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<script src="assets/js/signup.js?v=<?php echo time(); ?>"></script>
|
||||||
|
|
||||||
|
<?php include 'footer.php'; ?>
|
||||||
107
support.php
Normal file
107
support.php
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
<?php include 'header.php'; ?>
|
||||||
|
|
||||||
|
<div class="container mt-5">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-8 offset-md-2">
|
||||||
|
<h1 class="text-center mb-4">AI Support Assistant</h1>
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body" id="chat-window" style="height: 400px; overflow-y: scroll;">
|
||||||
|
<!-- Chat messages will appear here -->
|
||||||
|
<div class="d-flex flex-row justify-content-start mb-4">
|
||||||
|
<div class="p-3 ms-3" style="border-radius: 15px; background-color: #f5f6f7;">
|
||||||
|
<p class="small mb-0">Hello! How can I help you today? Ask me anything about our plans or services.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-footer text-muted d-flex justify-content-start align-items-center p-3">
|
||||||
|
<input type="text" class="form-control form-control-lg" id="user-input" placeholder="Type your message">
|
||||||
|
<button class="btn btn-primary ms-3" id="send-btn">Send</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const chatWindow = document.getElementById('chat-window');
|
||||||
|
const userInput = document.getElementById('user-input');
|
||||||
|
const sendBtn = document.getElementById('send-btn');
|
||||||
|
|
||||||
|
const addMessage = (message, sender) => {
|
||||||
|
const messageDiv = document.createElement('div');
|
||||||
|
const messageContent = document.createElement('div');
|
||||||
|
const text = document.createElement('p');
|
||||||
|
|
||||||
|
messageDiv.classList.add('d-flex', 'flex-row', 'mb-4');
|
||||||
|
messageContent.classList.add('p-3');
|
||||||
|
text.classList.add('small', 'mb-0');
|
||||||
|
|
||||||
|
text.innerText = message;
|
||||||
|
messageContent.appendChild(text);
|
||||||
|
|
||||||
|
if (sender === 'user') {
|
||||||
|
messageDiv.classList.add('justify-content-end');
|
||||||
|
messageContent.classList.add('me-3', 'text-white');
|
||||||
|
messageContent.style.borderRadius = '15px';
|
||||||
|
messageContent.style.backgroundColor = '#0d6efd'; // Bootstrap Primary Blue
|
||||||
|
} else {
|
||||||
|
messageDiv.classList.add('justify-content-start');
|
||||||
|
messageContent.classList.add('ms-3');
|
||||||
|
messageContent.style.borderRadius = '15px';
|
||||||
|
messageContent.style.backgroundColor = '#f5f6f7'; // Light grey
|
||||||
|
}
|
||||||
|
|
||||||
|
messageDiv.appendChild(messageContent);
|
||||||
|
chatWindow.appendChild(messageDiv);
|
||||||
|
chatWindow.scrollTop = chatWindow.scrollHeight; // Auto-scroll to the latest message
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSend = async () => {
|
||||||
|
const question = userInput.value.trim();
|
||||||
|
if (!question) return;
|
||||||
|
|
||||||
|
addMessage(question, 'user');
|
||||||
|
userInput.value = '';
|
||||||
|
userInput.disabled = true;
|
||||||
|
sendBtn.disabled = true;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch('/api/ai_support.php', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ question })
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error('Network response was not ok');
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await response.json();
|
||||||
|
|
||||||
|
if (data.reply) {
|
||||||
|
addMessage(data.reply, 'ai');
|
||||||
|
} else if (data.error) {
|
||||||
|
addMessage(data.error, 'ai');
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error:', error);
|
||||||
|
addMessage('Sorry, something went wrong. Please try again later.', 'ai');
|
||||||
|
} finally {
|
||||||
|
userInput.disabled = false;
|
||||||
|
sendBtn.disabled = false;
|
||||||
|
userInput.focus();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
sendBtn.addEventListener('click', handleSend);
|
||||||
|
userInput.addEventListener('keypress', (e) => {
|
||||||
|
if (e.key === 'Enter') {
|
||||||
|
handleSend();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<?php include 'footer.php'; ?>
|
||||||
22
vendor/autoload.php
vendored
Normal file
22
vendor/autoload.php
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// autoload.php @generated by Composer
|
||||||
|
|
||||||
|
if (PHP_VERSION_ID < 50600) {
|
||||||
|
if (!headers_sent()) {
|
||||||
|
header('HTTP/1.1 500 Internal Server Error');
|
||||||
|
}
|
||||||
|
$err = 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL;
|
||||||
|
if (!ini_get('display_errors')) {
|
||||||
|
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
|
||||||
|
fwrite(STDERR, $err);
|
||||||
|
} elseif (!headers_sent()) {
|
||||||
|
echo $err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new RuntimeException($err);
|
||||||
|
}
|
||||||
|
|
||||||
|
require_once __DIR__ . '/composer/autoload_real.php';
|
||||||
|
|
||||||
|
return ComposerAutoloaderInit4badc292822cc5b9fb20d40b3af3205b::getLoader();
|
||||||
579
vendor/composer/ClassLoader.php
vendored
Normal file
579
vendor/composer/ClassLoader.php
vendored
Normal file
@ -0,0 +1,579 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of Composer.
|
||||||
|
*
|
||||||
|
* (c) Nils Adermann <naderman@naderman.de>
|
||||||
|
* Jordi Boggiano <j.boggiano@seld.be>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Composer\Autoload;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
|
||||||
|
*
|
||||||
|
* $loader = new \Composer\Autoload\ClassLoader();
|
||||||
|
*
|
||||||
|
* // register classes with namespaces
|
||||||
|
* $loader->add('Symfony\Component', __DIR__.'/component');
|
||||||
|
* $loader->add('Symfony', __DIR__.'/framework');
|
||||||
|
*
|
||||||
|
* // activate the autoloader
|
||||||
|
* $loader->register();
|
||||||
|
*
|
||||||
|
* // to enable searching the include path (eg. for PEAR packages)
|
||||||
|
* $loader->setUseIncludePath(true);
|
||||||
|
*
|
||||||
|
* In this example, if you try to use a class in the Symfony\Component
|
||||||
|
* namespace or one of its children (Symfony\Component\Console for instance),
|
||||||
|
* the autoloader will first look for the class under the component/
|
||||||
|
* directory, and it will then fallback to the framework/ directory if not
|
||||||
|
* found before giving up.
|
||||||
|
*
|
||||||
|
* This class is loosely based on the Symfony UniversalClassLoader.
|
||||||
|
*
|
||||||
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
|
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||||
|
* @see https://www.php-fig.org/psr/psr-0/
|
||||||
|
* @see https://www.php-fig.org/psr/psr-4/
|
||||||
|
*/
|
||||||
|
class ClassLoader
|
||||||
|
{
|
||||||
|
/** @var \Closure(string):void */
|
||||||
|
private static $includeFile;
|
||||||
|
|
||||||
|
/** @var string|null */
|
||||||
|
private $vendorDir;
|
||||||
|
|
||||||
|
// PSR-4
|
||||||
|
/**
|
||||||
|
* @var array<string, array<string, int>>
|
||||||
|
*/
|
||||||
|
private $prefixLengthsPsr4 = array();
|
||||||
|
/**
|
||||||
|
* @var array<string, list<string>>
|
||||||
|
*/
|
||||||
|
private $prefixDirsPsr4 = array();
|
||||||
|
/**
|
||||||
|
* @var list<string>
|
||||||
|
*/
|
||||||
|
private $fallbackDirsPsr4 = array();
|
||||||
|
|
||||||
|
// PSR-0
|
||||||
|
/**
|
||||||
|
* List of PSR-0 prefixes
|
||||||
|
*
|
||||||
|
* Structured as array('F (first letter)' => array('Foo\Bar (full prefix)' => array('path', 'path2')))
|
||||||
|
*
|
||||||
|
* @var array<string, array<string, list<string>>>
|
||||||
|
*/
|
||||||
|
private $prefixesPsr0 = array();
|
||||||
|
/**
|
||||||
|
* @var list<string>
|
||||||
|
*/
|
||||||
|
private $fallbackDirsPsr0 = array();
|
||||||
|
|
||||||
|
/** @var bool */
|
||||||
|
private $useIncludePath = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array<string, string>
|
||||||
|
*/
|
||||||
|
private $classMap = array();
|
||||||
|
|
||||||
|
/** @var bool */
|
||||||
|
private $classMapAuthoritative = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array<string, bool>
|
||||||
|
*/
|
||||||
|
private $missingClasses = array();
|
||||||
|
|
||||||
|
/** @var string|null */
|
||||||
|
private $apcuPrefix;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array<string, self>
|
||||||
|
*/
|
||||||
|
private static $registeredLoaders = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string|null $vendorDir
|
||||||
|
*/
|
||||||
|
public function __construct($vendorDir = null)
|
||||||
|
{
|
||||||
|
$this->vendorDir = $vendorDir;
|
||||||
|
self::initializeIncludeClosure();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<string, list<string>>
|
||||||
|
*/
|
||||||
|
public function getPrefixes()
|
||||||
|
{
|
||||||
|
if (!empty($this->prefixesPsr0)) {
|
||||||
|
return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
|
||||||
|
}
|
||||||
|
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<string, list<string>>
|
||||||
|
*/
|
||||||
|
public function getPrefixesPsr4()
|
||||||
|
{
|
||||||
|
return $this->prefixDirsPsr4;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return list<string>
|
||||||
|
*/
|
||||||
|
public function getFallbackDirs()
|
||||||
|
{
|
||||||
|
return $this->fallbackDirsPsr0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return list<string>
|
||||||
|
*/
|
||||||
|
public function getFallbackDirsPsr4()
|
||||||
|
{
|
||||||
|
return $this->fallbackDirsPsr4;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<string, string> Array of classname => path
|
||||||
|
*/
|
||||||
|
public function getClassMap()
|
||||||
|
{
|
||||||
|
return $this->classMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array<string, string> $classMap Class to filename map
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function addClassMap(array $classMap)
|
||||||
|
{
|
||||||
|
if ($this->classMap) {
|
||||||
|
$this->classMap = array_merge($this->classMap, $classMap);
|
||||||
|
} else {
|
||||||
|
$this->classMap = $classMap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a set of PSR-0 directories for a given prefix, either
|
||||||
|
* appending or prepending to the ones previously set for this prefix.
|
||||||
|
*
|
||||||
|
* @param string $prefix The prefix
|
||||||
|
* @param list<string>|string $paths The PSR-0 root directories
|
||||||
|
* @param bool $prepend Whether to prepend the directories
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function add($prefix, $paths, $prepend = false)
|
||||||
|
{
|
||||||
|
$paths = (array) $paths;
|
||||||
|
if (!$prefix) {
|
||||||
|
if ($prepend) {
|
||||||
|
$this->fallbackDirsPsr0 = array_merge(
|
||||||
|
$paths,
|
||||||
|
$this->fallbackDirsPsr0
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$this->fallbackDirsPsr0 = array_merge(
|
||||||
|
$this->fallbackDirsPsr0,
|
||||||
|
$paths
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$first = $prefix[0];
|
||||||
|
if (!isset($this->prefixesPsr0[$first][$prefix])) {
|
||||||
|
$this->prefixesPsr0[$first][$prefix] = $paths;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ($prepend) {
|
||||||
|
$this->prefixesPsr0[$first][$prefix] = array_merge(
|
||||||
|
$paths,
|
||||||
|
$this->prefixesPsr0[$first][$prefix]
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$this->prefixesPsr0[$first][$prefix] = array_merge(
|
||||||
|
$this->prefixesPsr0[$first][$prefix],
|
||||||
|
$paths
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a set of PSR-4 directories for a given namespace, either
|
||||||
|
* appending or prepending to the ones previously set for this namespace.
|
||||||
|
*
|
||||||
|
* @param string $prefix The prefix/namespace, with trailing '\\'
|
||||||
|
* @param list<string>|string $paths The PSR-4 base directories
|
||||||
|
* @param bool $prepend Whether to prepend the directories
|
||||||
|
*
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function addPsr4($prefix, $paths, $prepend = false)
|
||||||
|
{
|
||||||
|
$paths = (array) $paths;
|
||||||
|
if (!$prefix) {
|
||||||
|
// Register directories for the root namespace.
|
||||||
|
if ($prepend) {
|
||||||
|
$this->fallbackDirsPsr4 = array_merge(
|
||||||
|
$paths,
|
||||||
|
$this->fallbackDirsPsr4
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$this->fallbackDirsPsr4 = array_merge(
|
||||||
|
$this->fallbackDirsPsr4,
|
||||||
|
$paths
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
|
||||||
|
// Register directories for a new namespace.
|
||||||
|
$length = strlen($prefix);
|
||||||
|
if ('\\' !== $prefix[$length - 1]) {
|
||||||
|
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
|
||||||
|
}
|
||||||
|
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
|
||||||
|
$this->prefixDirsPsr4[$prefix] = $paths;
|
||||||
|
} elseif ($prepend) {
|
||||||
|
// Prepend directories for an already registered namespace.
|
||||||
|
$this->prefixDirsPsr4[$prefix] = array_merge(
|
||||||
|
$paths,
|
||||||
|
$this->prefixDirsPsr4[$prefix]
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// Append directories for an already registered namespace.
|
||||||
|
$this->prefixDirsPsr4[$prefix] = array_merge(
|
||||||
|
$this->prefixDirsPsr4[$prefix],
|
||||||
|
$paths
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a set of PSR-0 directories for a given prefix,
|
||||||
|
* replacing any others previously set for this prefix.
|
||||||
|
*
|
||||||
|
* @param string $prefix The prefix
|
||||||
|
* @param list<string>|string $paths The PSR-0 base directories
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function set($prefix, $paths)
|
||||||
|
{
|
||||||
|
if (!$prefix) {
|
||||||
|
$this->fallbackDirsPsr0 = (array) $paths;
|
||||||
|
} else {
|
||||||
|
$this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a set of PSR-4 directories for a given namespace,
|
||||||
|
* replacing any others previously set for this namespace.
|
||||||
|
*
|
||||||
|
* @param string $prefix The prefix/namespace, with trailing '\\'
|
||||||
|
* @param list<string>|string $paths The PSR-4 base directories
|
||||||
|
*
|
||||||
|
* @throws \InvalidArgumentException
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function setPsr4($prefix, $paths)
|
||||||
|
{
|
||||||
|
if (!$prefix) {
|
||||||
|
$this->fallbackDirsPsr4 = (array) $paths;
|
||||||
|
} else {
|
||||||
|
$length = strlen($prefix);
|
||||||
|
if ('\\' !== $prefix[$length - 1]) {
|
||||||
|
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
|
||||||
|
}
|
||||||
|
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
|
||||||
|
$this->prefixDirsPsr4[$prefix] = (array) $paths;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Turns on searching the include path for class files.
|
||||||
|
*
|
||||||
|
* @param bool $useIncludePath
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function setUseIncludePath($useIncludePath)
|
||||||
|
{
|
||||||
|
$this->useIncludePath = $useIncludePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Can be used to check if the autoloader uses the include path to check
|
||||||
|
* for classes.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function getUseIncludePath()
|
||||||
|
{
|
||||||
|
return $this->useIncludePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Turns off searching the prefix and fallback directories for classes
|
||||||
|
* that have not been registered with the class map.
|
||||||
|
*
|
||||||
|
* @param bool $classMapAuthoritative
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function setClassMapAuthoritative($classMapAuthoritative)
|
||||||
|
{
|
||||||
|
$this->classMapAuthoritative = $classMapAuthoritative;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Should class lookup fail if not found in the current class map?
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isClassMapAuthoritative()
|
||||||
|
{
|
||||||
|
return $this->classMapAuthoritative;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* APCu prefix to use to cache found/not-found classes, if the extension is enabled.
|
||||||
|
*
|
||||||
|
* @param string|null $apcuPrefix
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function setApcuPrefix($apcuPrefix)
|
||||||
|
{
|
||||||
|
$this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The APCu prefix in use, or null if APCu caching is not enabled.
|
||||||
|
*
|
||||||
|
* @return string|null
|
||||||
|
*/
|
||||||
|
public function getApcuPrefix()
|
||||||
|
{
|
||||||
|
return $this->apcuPrefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers this instance as an autoloader.
|
||||||
|
*
|
||||||
|
* @param bool $prepend Whether to prepend the autoloader or not
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function register($prepend = false)
|
||||||
|
{
|
||||||
|
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
|
||||||
|
|
||||||
|
if (null === $this->vendorDir) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($prepend) {
|
||||||
|
self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
|
||||||
|
} else {
|
||||||
|
unset(self::$registeredLoaders[$this->vendorDir]);
|
||||||
|
self::$registeredLoaders[$this->vendorDir] = $this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unregisters this instance as an autoloader.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function unregister()
|
||||||
|
{
|
||||||
|
spl_autoload_unregister(array($this, 'loadClass'));
|
||||||
|
|
||||||
|
if (null !== $this->vendorDir) {
|
||||||
|
unset(self::$registeredLoaders[$this->vendorDir]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the given class or interface.
|
||||||
|
*
|
||||||
|
* @param string $class The name of the class
|
||||||
|
* @return true|null True if loaded, null otherwise
|
||||||
|
*/
|
||||||
|
public function loadClass($class)
|
||||||
|
{
|
||||||
|
if ($file = $this->findFile($class)) {
|
||||||
|
$includeFile = self::$includeFile;
|
||||||
|
$includeFile($file);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds the path to the file where the class is defined.
|
||||||
|
*
|
||||||
|
* @param string $class The name of the class
|
||||||
|
*
|
||||||
|
* @return string|false The path if found, false otherwise
|
||||||
|
*/
|
||||||
|
public function findFile($class)
|
||||||
|
{
|
||||||
|
// class map lookup
|
||||||
|
if (isset($this->classMap[$class])) {
|
||||||
|
return $this->classMap[$class];
|
||||||
|
}
|
||||||
|
if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (null !== $this->apcuPrefix) {
|
||||||
|
$file = apcu_fetch($this->apcuPrefix.$class, $hit);
|
||||||
|
if ($hit) {
|
||||||
|
return $file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$file = $this->findFileWithExtension($class, '.php');
|
||||||
|
|
||||||
|
// Search for Hack files if we are running on HHVM
|
||||||
|
if (false === $file && defined('HHVM_VERSION')) {
|
||||||
|
$file = $this->findFileWithExtension($class, '.hh');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null !== $this->apcuPrefix) {
|
||||||
|
apcu_add($this->apcuPrefix.$class, $file);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (false === $file) {
|
||||||
|
// Remember that this class does not exist.
|
||||||
|
$this->missingClasses[$class] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $file;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the currently registered loaders keyed by their corresponding vendor directories.
|
||||||
|
*
|
||||||
|
* @return array<string, self>
|
||||||
|
*/
|
||||||
|
public static function getRegisteredLoaders()
|
||||||
|
{
|
||||||
|
return self::$registeredLoaders;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $class
|
||||||
|
* @param string $ext
|
||||||
|
* @return string|false
|
||||||
|
*/
|
||||||
|
private function findFileWithExtension($class, $ext)
|
||||||
|
{
|
||||||
|
// PSR-4 lookup
|
||||||
|
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
|
||||||
|
|
||||||
|
$first = $class[0];
|
||||||
|
if (isset($this->prefixLengthsPsr4[$first])) {
|
||||||
|
$subPath = $class;
|
||||||
|
while (false !== $lastPos = strrpos($subPath, '\\')) {
|
||||||
|
$subPath = substr($subPath, 0, $lastPos);
|
||||||
|
$search = $subPath . '\\';
|
||||||
|
if (isset($this->prefixDirsPsr4[$search])) {
|
||||||
|
$pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
|
||||||
|
foreach ($this->prefixDirsPsr4[$search] as $dir) {
|
||||||
|
if (file_exists($file = $dir . $pathEnd)) {
|
||||||
|
return $file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PSR-4 fallback dirs
|
||||||
|
foreach ($this->fallbackDirsPsr4 as $dir) {
|
||||||
|
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
|
||||||
|
return $file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PSR-0 lookup
|
||||||
|
if (false !== $pos = strrpos($class, '\\')) {
|
||||||
|
// namespaced class name
|
||||||
|
$logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
|
||||||
|
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
|
||||||
|
} else {
|
||||||
|
// PEAR-like class name
|
||||||
|
$logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($this->prefixesPsr0[$first])) {
|
||||||
|
foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
|
||||||
|
if (0 === strpos($class, $prefix)) {
|
||||||
|
foreach ($dirs as $dir) {
|
||||||
|
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
|
||||||
|
return $file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PSR-0 fallback dirs
|
||||||
|
foreach ($this->fallbackDirsPsr0 as $dir) {
|
||||||
|
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
|
||||||
|
return $file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PSR-0 include paths.
|
||||||
|
if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
|
||||||
|
return $file;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
private static function initializeIncludeClosure()
|
||||||
|
{
|
||||||
|
if (self::$includeFile !== null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scope isolated include.
|
||||||
|
*
|
||||||
|
* Prevents access to $this/self from included files.
|
||||||
|
*
|
||||||
|
* @param string $file
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
self::$includeFile = \Closure::bind(static function($file) {
|
||||||
|
include $file;
|
||||||
|
}, null, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
396
vendor/composer/InstalledVersions.php
vendored
Normal file
396
vendor/composer/InstalledVersions.php
vendored
Normal file
@ -0,0 +1,396 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of Composer.
|
||||||
|
*
|
||||||
|
* (c) Nils Adermann <naderman@naderman.de>
|
||||||
|
* Jordi Boggiano <j.boggiano@seld.be>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Composer;
|
||||||
|
|
||||||
|
use Composer\Autoload\ClassLoader;
|
||||||
|
use Composer\Semver\VersionParser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is copied in every Composer installed project and available to all
|
||||||
|
*
|
||||||
|
* See also https://getcomposer.org/doc/07-runtime.md#installed-versions
|
||||||
|
*
|
||||||
|
* To require its presence, you can require `composer-runtime-api ^2.0`
|
||||||
|
*
|
||||||
|
* @final
|
||||||
|
*/
|
||||||
|
class InstalledVersions
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var string|null if set (by reflection by Composer), this should be set to the path where this class is being copied to
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
private static $selfDir = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var mixed[]|null
|
||||||
|
* @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null
|
||||||
|
*/
|
||||||
|
private static $installed;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
private static $installedIsLocalDir;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var bool|null
|
||||||
|
*/
|
||||||
|
private static $canGetVendors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array[]
|
||||||
|
* @psalm-var array<string, array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
|
||||||
|
*/
|
||||||
|
private static $installedByVendor = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of all package names which are present, either by being installed, replaced or provided
|
||||||
|
*
|
||||||
|
* @return string[]
|
||||||
|
* @psalm-return list<string>
|
||||||
|
*/
|
||||||
|
public static function getInstalledPackages()
|
||||||
|
{
|
||||||
|
$packages = array();
|
||||||
|
foreach (self::getInstalled() as $installed) {
|
||||||
|
$packages[] = array_keys($installed['versions']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (1 === \count($packages)) {
|
||||||
|
return $packages[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return array_keys(array_flip(\call_user_func_array('array_merge', $packages)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of all package names with a specific type e.g. 'library'
|
||||||
|
*
|
||||||
|
* @param string $type
|
||||||
|
* @return string[]
|
||||||
|
* @psalm-return list<string>
|
||||||
|
*/
|
||||||
|
public static function getInstalledPackagesByType($type)
|
||||||
|
{
|
||||||
|
$packagesByType = array();
|
||||||
|
|
||||||
|
foreach (self::getInstalled() as $installed) {
|
||||||
|
foreach ($installed['versions'] as $name => $package) {
|
||||||
|
if (isset($package['type']) && $package['type'] === $type) {
|
||||||
|
$packagesByType[] = $name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $packagesByType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the given package is installed
|
||||||
|
*
|
||||||
|
* This also returns true if the package name is provided or replaced by another package
|
||||||
|
*
|
||||||
|
* @param string $packageName
|
||||||
|
* @param bool $includeDevRequirements
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function isInstalled($packageName, $includeDevRequirements = true)
|
||||||
|
{
|
||||||
|
foreach (self::getInstalled() as $installed) {
|
||||||
|
if (isset($installed['versions'][$packageName])) {
|
||||||
|
return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the given package satisfies a version constraint
|
||||||
|
*
|
||||||
|
* e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call:
|
||||||
|
*
|
||||||
|
* Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3')
|
||||||
|
*
|
||||||
|
* @param VersionParser $parser Install composer/semver to have access to this class and functionality
|
||||||
|
* @param string $packageName
|
||||||
|
* @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function satisfies(VersionParser $parser, $packageName, $constraint)
|
||||||
|
{
|
||||||
|
$constraint = $parser->parseConstraints((string) $constraint);
|
||||||
|
$provided = $parser->parseConstraints(self::getVersionRanges($packageName));
|
||||||
|
|
||||||
|
return $provided->matches($constraint);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a version constraint representing all the range(s) which are installed for a given package
|
||||||
|
*
|
||||||
|
* It is easier to use this via isInstalled() with the $constraint argument if you need to check
|
||||||
|
* whether a given version of a package is installed, and not just whether it exists
|
||||||
|
*
|
||||||
|
* @param string $packageName
|
||||||
|
* @return string Version constraint usable with composer/semver
|
||||||
|
*/
|
||||||
|
public static function getVersionRanges($packageName)
|
||||||
|
{
|
||||||
|
foreach (self::getInstalled() as $installed) {
|
||||||
|
if (!isset($installed['versions'][$packageName])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$ranges = array();
|
||||||
|
if (isset($installed['versions'][$packageName]['pretty_version'])) {
|
||||||
|
$ranges[] = $installed['versions'][$packageName]['pretty_version'];
|
||||||
|
}
|
||||||
|
if (array_key_exists('aliases', $installed['versions'][$packageName])) {
|
||||||
|
$ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']);
|
||||||
|
}
|
||||||
|
if (array_key_exists('replaced', $installed['versions'][$packageName])) {
|
||||||
|
$ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']);
|
||||||
|
}
|
||||||
|
if (array_key_exists('provided', $installed['versions'][$packageName])) {
|
||||||
|
$ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return implode(' || ', $ranges);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $packageName
|
||||||
|
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
|
||||||
|
*/
|
||||||
|
public static function getVersion($packageName)
|
||||||
|
{
|
||||||
|
foreach (self::getInstalled() as $installed) {
|
||||||
|
if (!isset($installed['versions'][$packageName])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($installed['versions'][$packageName]['version'])) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $installed['versions'][$packageName]['version'];
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $packageName
|
||||||
|
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
|
||||||
|
*/
|
||||||
|
public static function getPrettyVersion($packageName)
|
||||||
|
{
|
||||||
|
foreach (self::getInstalled() as $installed) {
|
||||||
|
if (!isset($installed['versions'][$packageName])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($installed['versions'][$packageName]['pretty_version'])) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $installed['versions'][$packageName]['pretty_version'];
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $packageName
|
||||||
|
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference
|
||||||
|
*/
|
||||||
|
public static function getReference($packageName)
|
||||||
|
{
|
||||||
|
foreach (self::getInstalled() as $installed) {
|
||||||
|
if (!isset($installed['versions'][$packageName])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($installed['versions'][$packageName]['reference'])) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $installed['versions'][$packageName]['reference'];
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $packageName
|
||||||
|
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path.
|
||||||
|
*/
|
||||||
|
public static function getInstallPath($packageName)
|
||||||
|
{
|
||||||
|
foreach (self::getInstalled() as $installed) {
|
||||||
|
if (!isset($installed['versions'][$packageName])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
* @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}
|
||||||
|
*/
|
||||||
|
public static function getRootPackage()
|
||||||
|
{
|
||||||
|
$installed = self::getInstalled();
|
||||||
|
|
||||||
|
return $installed[0]['root'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the raw installed.php data for custom implementations
|
||||||
|
*
|
||||||
|
* @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect.
|
||||||
|
* @return array[]
|
||||||
|
* @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}
|
||||||
|
*/
|
||||||
|
public static function getRawData()
|
||||||
|
{
|
||||||
|
@trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED);
|
||||||
|
|
||||||
|
if (null === self::$installed) {
|
||||||
|
// only require the installed.php file if this file is loaded from its dumped location,
|
||||||
|
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
|
||||||
|
if (substr(__DIR__, -8, 1) !== 'C') {
|
||||||
|
self::$installed = include __DIR__ . '/installed.php';
|
||||||
|
} else {
|
||||||
|
self::$installed = array();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::$installed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the raw data of all installed.php which are currently loaded for custom implementations
|
||||||
|
*
|
||||||
|
* @return array[]
|
||||||
|
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
|
||||||
|
*/
|
||||||
|
public static function getAllRawData()
|
||||||
|
{
|
||||||
|
return self::getInstalled();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lets you reload the static array from another file
|
||||||
|
*
|
||||||
|
* This is only useful for complex integrations in which a project needs to use
|
||||||
|
* this class but then also needs to execute another project's autoloader in process,
|
||||||
|
* and wants to ensure both projects have access to their version of installed.php.
|
||||||
|
*
|
||||||
|
* A typical case would be PHPUnit, where it would need to make sure it reads all
|
||||||
|
* the data it needs from this class, then call reload() with
|
||||||
|
* `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure
|
||||||
|
* the project in which it runs can then also use this class safely, without
|
||||||
|
* interference between PHPUnit's dependencies and the project's dependencies.
|
||||||
|
*
|
||||||
|
* @param array[] $data A vendor/composer/installed.php data set
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
* @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $data
|
||||||
|
*/
|
||||||
|
public static function reload($data)
|
||||||
|
{
|
||||||
|
self::$installed = $data;
|
||||||
|
self::$installedByVendor = array();
|
||||||
|
|
||||||
|
// when using reload, we disable the duplicate protection to ensure that self::$installed data is
|
||||||
|
// always returned, but we cannot know whether it comes from the installed.php in __DIR__ or not,
|
||||||
|
// so we have to assume it does not, and that may result in duplicate data being returned when listing
|
||||||
|
// all installed packages for example
|
||||||
|
self::$installedIsLocalDir = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private static function getSelfDir()
|
||||||
|
{
|
||||||
|
if (self::$selfDir === null) {
|
||||||
|
self::$selfDir = strtr(__DIR__, '\\', '/');
|
||||||
|
}
|
||||||
|
|
||||||
|
return self::$selfDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array[]
|
||||||
|
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
|
||||||
|
*/
|
||||||
|
private static function getInstalled()
|
||||||
|
{
|
||||||
|
if (null === self::$canGetVendors) {
|
||||||
|
self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders');
|
||||||
|
}
|
||||||
|
|
||||||
|
$installed = array();
|
||||||
|
$copiedLocalDir = false;
|
||||||
|
|
||||||
|
if (self::$canGetVendors) {
|
||||||
|
$selfDir = self::getSelfDir();
|
||||||
|
foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
|
||||||
|
$vendorDir = strtr($vendorDir, '\\', '/');
|
||||||
|
if (isset(self::$installedByVendor[$vendorDir])) {
|
||||||
|
$installed[] = self::$installedByVendor[$vendorDir];
|
||||||
|
} elseif (is_file($vendorDir.'/composer/installed.php')) {
|
||||||
|
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
|
||||||
|
$required = require $vendorDir.'/composer/installed.php';
|
||||||
|
self::$installedByVendor[$vendorDir] = $required;
|
||||||
|
$installed[] = $required;
|
||||||
|
if (self::$installed === null && $vendorDir.'/composer' === $selfDir) {
|
||||||
|
self::$installed = $required;
|
||||||
|
self::$installedIsLocalDir = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (self::$installedIsLocalDir && $vendorDir.'/composer' === $selfDir) {
|
||||||
|
$copiedLocalDir = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null === self::$installed) {
|
||||||
|
// only require the installed.php file if this file is loaded from its dumped location,
|
||||||
|
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
|
||||||
|
if (substr(__DIR__, -8, 1) !== 'C') {
|
||||||
|
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
|
||||||
|
$required = require __DIR__ . '/installed.php';
|
||||||
|
self::$installed = $required;
|
||||||
|
} else {
|
||||||
|
self::$installed = array();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self::$installed !== array() && !$copiedLocalDir) {
|
||||||
|
$installed[] = self::$installed;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $installed;
|
||||||
|
}
|
||||||
|
}
|
||||||
21
vendor/composer/LICENSE
vendored
Normal file
21
vendor/composer/LICENSE
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
|
||||||
|
Copyright (c) Nils Adermann, Jordi Boggiano
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
35
vendor/composer/autoload_classmap.php
vendored
Normal file
35
vendor/composer/autoload_classmap.php
vendored
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// autoload_classmap.php @generated by Composer
|
||||||
|
|
||||||
|
$vendorDir = dirname(__DIR__);
|
||||||
|
$baseDir = dirname($vendorDir);
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
|
||||||
|
'Stripe' => $vendorDir . '/stripe/stripe-php/lib/Stripe/Stripe.php',
|
||||||
|
'Stripe_Account' => $vendorDir . '/stripe/stripe-php/lib/Stripe/Account.php',
|
||||||
|
'Stripe_ApiConnectionError' => $vendorDir . '/stripe/stripe-php/lib/Stripe/ApiConnectionError.php',
|
||||||
|
'Stripe_ApiError' => $vendorDir . '/stripe/stripe-php/lib/Stripe/ApiError.php',
|
||||||
|
'Stripe_ApiRequestor' => $vendorDir . '/stripe/stripe-php/lib/Stripe/ApiRequestor.php',
|
||||||
|
'Stripe_ApiResource' => $vendorDir . '/stripe/stripe-php/lib/Stripe/ApiResource.php',
|
||||||
|
'Stripe_AuthenticationError' => $vendorDir . '/stripe/stripe-php/lib/Stripe/AuthenticationError.php',
|
||||||
|
'Stripe_CardError' => $vendorDir . '/stripe/stripe-php/lib/Stripe/CardError.php',
|
||||||
|
'Stripe_Charge' => $vendorDir . '/stripe/stripe-php/lib/Stripe/Charge.php',
|
||||||
|
'Stripe_Coupon' => $vendorDir . '/stripe/stripe-php/lib/Stripe/Coupon.php',
|
||||||
|
'Stripe_Customer' => $vendorDir . '/stripe/stripe-php/lib/Stripe/Customer.php',
|
||||||
|
'Stripe_Error' => $vendorDir . '/stripe/stripe-php/lib/Stripe/Error.php',
|
||||||
|
'Stripe_Event' => $vendorDir . '/stripe/stripe-php/lib/Stripe/Event.php',
|
||||||
|
'Stripe_InvalidRequestError' => $vendorDir . '/stripe/stripe-php/lib/Stripe/InvalidRequestError.php',
|
||||||
|
'Stripe_Invoice' => $vendorDir . '/stripe/stripe-php/lib/Stripe/Invoice.php',
|
||||||
|
'Stripe_InvoiceItem' => $vendorDir . '/stripe/stripe-php/lib/Stripe/InvoiceItem.php',
|
||||||
|
'Stripe_List' => $vendorDir . '/stripe/stripe-php/lib/Stripe/List.php',
|
||||||
|
'Stripe_Object' => $vendorDir . '/stripe/stripe-php/lib/Stripe/Object.php',
|
||||||
|
'Stripe_Plan' => $vendorDir . '/stripe/stripe-php/lib/Stripe/Plan.php',
|
||||||
|
'Stripe_Recipient' => $vendorDir . '/stripe/stripe-php/lib/Stripe/Recipient.php',
|
||||||
|
'Stripe_SingletonApiResource' => $vendorDir . '/stripe/stripe-php/lib/Stripe/SingletonApiResource.php',
|
||||||
|
'Stripe_Token' => $vendorDir . '/stripe/stripe-php/lib/Stripe/Token.php',
|
||||||
|
'Stripe_Transfer' => $vendorDir . '/stripe/stripe-php/lib/Stripe/Transfer.php',
|
||||||
|
'Stripe_Util' => $vendorDir . '/stripe/stripe-php/lib/Stripe/Util.php',
|
||||||
|
'Stripe_Util_Set' => $vendorDir . '/stripe/stripe-php/lib/Stripe/Util/Set.php',
|
||||||
|
);
|
||||||
9
vendor/composer/autoload_namespaces.php
vendored
Normal file
9
vendor/composer/autoload_namespaces.php
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// autoload_namespaces.php @generated by Composer
|
||||||
|
|
||||||
|
$vendorDir = dirname(__DIR__);
|
||||||
|
$baseDir = dirname($vendorDir);
|
||||||
|
|
||||||
|
return array(
|
||||||
|
);
|
||||||
9
vendor/composer/autoload_psr4.php
vendored
Normal file
9
vendor/composer/autoload_psr4.php
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// autoload_psr4.php @generated by Composer
|
||||||
|
|
||||||
|
$vendorDir = dirname(__DIR__);
|
||||||
|
$baseDir = dirname($vendorDir);
|
||||||
|
|
||||||
|
return array(
|
||||||
|
);
|
||||||
38
vendor/composer/autoload_real.php
vendored
Normal file
38
vendor/composer/autoload_real.php
vendored
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// autoload_real.php @generated by Composer
|
||||||
|
|
||||||
|
class ComposerAutoloaderInit4badc292822cc5b9fb20d40b3af3205b
|
||||||
|
{
|
||||||
|
private static $loader;
|
||||||
|
|
||||||
|
public static function loadClassLoader($class)
|
||||||
|
{
|
||||||
|
if ('Composer\Autoload\ClassLoader' === $class) {
|
||||||
|
require __DIR__ . '/ClassLoader.php';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return \Composer\Autoload\ClassLoader
|
||||||
|
*/
|
||||||
|
public static function getLoader()
|
||||||
|
{
|
||||||
|
if (null !== self::$loader) {
|
||||||
|
return self::$loader;
|
||||||
|
}
|
||||||
|
|
||||||
|
require __DIR__ . '/platform_check.php';
|
||||||
|
|
||||||
|
spl_autoload_register(array('ComposerAutoloaderInit4badc292822cc5b9fb20d40b3af3205b', 'loadClassLoader'), true, true);
|
||||||
|
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
|
||||||
|
spl_autoload_unregister(array('ComposerAutoloaderInit4badc292822cc5b9fb20d40b3af3205b', 'loadClassLoader'));
|
||||||
|
|
||||||
|
require __DIR__ . '/autoload_static.php';
|
||||||
|
call_user_func(\Composer\Autoload\ComposerStaticInit4badc292822cc5b9fb20d40b3af3205b::getInitializer($loader));
|
||||||
|
|
||||||
|
$loader->register(true);
|
||||||
|
|
||||||
|
return $loader;
|
||||||
|
}
|
||||||
|
}
|
||||||
45
vendor/composer/autoload_static.php
vendored
Normal file
45
vendor/composer/autoload_static.php
vendored
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// autoload_static.php @generated by Composer
|
||||||
|
|
||||||
|
namespace Composer\Autoload;
|
||||||
|
|
||||||
|
class ComposerStaticInit4badc292822cc5b9fb20d40b3af3205b
|
||||||
|
{
|
||||||
|
public static $classMap = array (
|
||||||
|
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
|
||||||
|
'Stripe' => __DIR__ . '/..' . '/stripe/stripe-php/lib/Stripe/Stripe.php',
|
||||||
|
'Stripe_Account' => __DIR__ . '/..' . '/stripe/stripe-php/lib/Stripe/Account.php',
|
||||||
|
'Stripe_ApiConnectionError' => __DIR__ . '/..' . '/stripe/stripe-php/lib/Stripe/ApiConnectionError.php',
|
||||||
|
'Stripe_ApiError' => __DIR__ . '/..' . '/stripe/stripe-php/lib/Stripe/ApiError.php',
|
||||||
|
'Stripe_ApiRequestor' => __DIR__ . '/..' . '/stripe/stripe-php/lib/Stripe/ApiRequestor.php',
|
||||||
|
'Stripe_ApiResource' => __DIR__ . '/..' . '/stripe/stripe-php/lib/Stripe/ApiResource.php',
|
||||||
|
'Stripe_AuthenticationError' => __DIR__ . '/..' . '/stripe/stripe-php/lib/Stripe/AuthenticationError.php',
|
||||||
|
'Stripe_CardError' => __DIR__ . '/..' . '/stripe/stripe-php/lib/Stripe/CardError.php',
|
||||||
|
'Stripe_Charge' => __DIR__ . '/..' . '/stripe/stripe-php/lib/Stripe/Charge.php',
|
||||||
|
'Stripe_Coupon' => __DIR__ . '/..' . '/stripe/stripe-php/lib/Stripe/Coupon.php',
|
||||||
|
'Stripe_Customer' => __DIR__ . '/..' . '/stripe/stripe-php/lib/Stripe/Customer.php',
|
||||||
|
'Stripe_Error' => __DIR__ . '/..' . '/stripe/stripe-php/lib/Stripe/Error.php',
|
||||||
|
'Stripe_Event' => __DIR__ . '/..' . '/stripe/stripe-php/lib/Stripe/Event.php',
|
||||||
|
'Stripe_InvalidRequestError' => __DIR__ . '/..' . '/stripe/stripe-php/lib/Stripe/InvalidRequestError.php',
|
||||||
|
'Stripe_Invoice' => __DIR__ . '/..' . '/stripe/stripe-php/lib/Stripe/Invoice.php',
|
||||||
|
'Stripe_InvoiceItem' => __DIR__ . '/..' . '/stripe/stripe-php/lib/Stripe/InvoiceItem.php',
|
||||||
|
'Stripe_List' => __DIR__ . '/..' . '/stripe/stripe-php/lib/Stripe/List.php',
|
||||||
|
'Stripe_Object' => __DIR__ . '/..' . '/stripe/stripe-php/lib/Stripe/Object.php',
|
||||||
|
'Stripe_Plan' => __DIR__ . '/..' . '/stripe/stripe-php/lib/Stripe/Plan.php',
|
||||||
|
'Stripe_Recipient' => __DIR__ . '/..' . '/stripe/stripe-php/lib/Stripe/Recipient.php',
|
||||||
|
'Stripe_SingletonApiResource' => __DIR__ . '/..' . '/stripe/stripe-php/lib/Stripe/SingletonApiResource.php',
|
||||||
|
'Stripe_Token' => __DIR__ . '/..' . '/stripe/stripe-php/lib/Stripe/Token.php',
|
||||||
|
'Stripe_Transfer' => __DIR__ . '/..' . '/stripe/stripe-php/lib/Stripe/Transfer.php',
|
||||||
|
'Stripe_Util' => __DIR__ . '/..' . '/stripe/stripe-php/lib/Stripe/Util.php',
|
||||||
|
'Stripe_Util_Set' => __DIR__ . '/..' . '/stripe/stripe-php/lib/Stripe/Util/Set.php',
|
||||||
|
);
|
||||||
|
|
||||||
|
public static function getInitializer(ClassLoader $loader)
|
||||||
|
{
|
||||||
|
return \Closure::bind(function () use ($loader) {
|
||||||
|
$loader->classMap = ComposerStaticInit4badc292822cc5b9fb20d40b3af3205b::$classMap;
|
||||||
|
|
||||||
|
}, null, ClassLoader::class);
|
||||||
|
}
|
||||||
|
}
|
||||||
59
vendor/composer/installed.json
vendored
Normal file
59
vendor/composer/installed.json
vendored
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
{
|
||||||
|
"packages": [
|
||||||
|
{
|
||||||
|
"name": "stripe/stripe-php",
|
||||||
|
"version": "v1.8.0",
|
||||||
|
"version_normalized": "1.8.0.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/stripe/stripe-php.git",
|
||||||
|
"reference": "5eba614baf4adefffdd59d196679a16d7baf70da"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/stripe/stripe-php/zipball/5eba614baf4adefffdd59d196679a16d7baf70da",
|
||||||
|
"reference": "5eba614baf4adefffdd59d196679a16d7baf70da",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"ext-curl": "*",
|
||||||
|
"php": ">=5.2"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"vierbergenlars/simpletest": "*"
|
||||||
|
},
|
||||||
|
"time": "2013-04-12T18:56:41+00:00",
|
||||||
|
"type": "library",
|
||||||
|
"installation-source": "dist",
|
||||||
|
"autoload": {
|
||||||
|
"classmap": [
|
||||||
|
"lib/Stripe/"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Stripe and contributors",
|
||||||
|
"homepage": "https://github.com/stripe/stripe-php/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Stripe PHP Library",
|
||||||
|
"homepage": "https://stripe.com/",
|
||||||
|
"keywords": [
|
||||||
|
"api",
|
||||||
|
"payment processing",
|
||||||
|
"stripe"
|
||||||
|
],
|
||||||
|
"support": {
|
||||||
|
"issues": "https://github.com/stripe/stripe-php/issues",
|
||||||
|
"source": "https://github.com/stripe/stripe-php/tree/transfers-recipients"
|
||||||
|
},
|
||||||
|
"install-path": "../stripe/stripe-php"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"dev-package-names": []
|
||||||
|
}
|
||||||
32
vendor/composer/installed.php
vendored
Normal file
32
vendor/composer/installed.php
vendored
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<?php return array(
|
||||||
|
'root' => array(
|
||||||
|
'name' => 'flatlogic/customer-project',
|
||||||
|
'pretty_version' => 'dev-master',
|
||||||
|
'version' => 'dev-master',
|
||||||
|
'reference' => 'b29f71a77323569c4ea1b072b00995babc99f322',
|
||||||
|
'type' => 'library',
|
||||||
|
'install_path' => __DIR__ . '/../../',
|
||||||
|
'aliases' => array(),
|
||||||
|
'dev' => true,
|
||||||
|
),
|
||||||
|
'versions' => array(
|
||||||
|
'flatlogic/customer-project' => array(
|
||||||
|
'pretty_version' => 'dev-master',
|
||||||
|
'version' => 'dev-master',
|
||||||
|
'reference' => 'b29f71a77323569c4ea1b072b00995babc99f322',
|
||||||
|
'type' => 'library',
|
||||||
|
'install_path' => __DIR__ . '/../../',
|
||||||
|
'aliases' => array(),
|
||||||
|
'dev_requirement' => false,
|
||||||
|
),
|
||||||
|
'stripe/stripe-php' => array(
|
||||||
|
'pretty_version' => 'v1.8.0',
|
||||||
|
'version' => '1.8.0.0',
|
||||||
|
'reference' => '5eba614baf4adefffdd59d196679a16d7baf70da',
|
||||||
|
'type' => 'library',
|
||||||
|
'install_path' => __DIR__ . '/../stripe/stripe-php',
|
||||||
|
'aliases' => array(),
|
||||||
|
'dev_requirement' => false,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
25
vendor/composer/platform_check.php
vendored
Normal file
25
vendor/composer/platform_check.php
vendored
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// platform_check.php @generated by Composer
|
||||||
|
|
||||||
|
$issues = array();
|
||||||
|
|
||||||
|
if (!(PHP_VERSION_ID >= 50200)) {
|
||||||
|
$issues[] = 'Your Composer dependencies require a PHP version ">= 5.2.0". You are running ' . PHP_VERSION . '.';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($issues) {
|
||||||
|
if (!headers_sent()) {
|
||||||
|
header('HTTP/1.1 500 Internal Server Error');
|
||||||
|
}
|
||||||
|
if (!ini_get('display_errors')) {
|
||||||
|
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
|
||||||
|
fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL);
|
||||||
|
} elseif (!headers_sent()) {
|
||||||
|
echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new \RuntimeException(
|
||||||
|
'Composer detected issues in your platform: ' . implode(' ', $issues)
|
||||||
|
);
|
||||||
|
}
|
||||||
11
vendor/stripe/stripe-php/.gitignore
vendored
Normal file
11
vendor/stripe/stripe-php/.gitignore
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
# Mac OS X dumps these all over the place.
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
# Ignore the SimpleTest library if it is installed to /test/.
|
||||||
|
/test/simpletest/
|
||||||
|
|
||||||
|
# Ignore the /vendor/ directory for people using composer
|
||||||
|
/vendor/
|
||||||
|
|
||||||
|
# If the vendor directory isn't being commited the composer.lock file should also be ignored
|
||||||
|
composer.lock
|
||||||
9
vendor/stripe/stripe-php/.travis.yml
vendored
Normal file
9
vendor/stripe/stripe-php/.travis.yml
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
language: php
|
||||||
|
php:
|
||||||
|
- 5.2
|
||||||
|
- 5.3
|
||||||
|
- 5.4
|
||||||
|
before_script:
|
||||||
|
- wget http://voxel.dl.sourceforge.net/project/simpletest/simpletest/simpletest_1.1/simpletest_1.1.0.tar.gz
|
||||||
|
- tar xf simpletest_1.1.0.tar.gz -C test
|
||||||
|
script: php test/Stripe.php
|
||||||
96
vendor/stripe/stripe-php/CHANGELOG
vendored
Normal file
96
vendor/stripe/stripe-php/CHANGELOG
vendored
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
=== 1.8.0 2013-04-11
|
||||||
|
|
||||||
|
* Allow Transfers to be creatable
|
||||||
|
* Add new Recipient resource
|
||||||
|
|
||||||
|
=== 1.7.15 2013-02-21
|
||||||
|
|
||||||
|
* Add 'id' to the list of permanent object attributes
|
||||||
|
|
||||||
|
=== 1.7.14 2013-02-20
|
||||||
|
|
||||||
|
* Don't re-encode strings that are already encoded in UTF-8. If you
|
||||||
|
were previously using plan or coupon objects with UTF-8 IDs, they
|
||||||
|
may have been treated as ISO-8859-1 (Latin-1) and encoded to UTF-8 a
|
||||||
|
2nd time. You may now need to pass the IDs to utf8_encode before
|
||||||
|
passing them to Stripe_Plan::retrieve or Stripe_Coupon::retrieve.
|
||||||
|
* Ensure that all input is encoded in UTF-8 before submitting it to
|
||||||
|
Stripe's servers. (github issue #27)
|
||||||
|
|
||||||
|
=== 1.7.13 2013-02-01
|
||||||
|
|
||||||
|
* Add support for passing options when retrieving Stripe objects
|
||||||
|
e.g., Stripe_Charge::retrieve(array("id"=>"foo", "expand" => array("customer")))
|
||||||
|
Stripe_Charge::retrieve("foo") will continue to work
|
||||||
|
|
||||||
|
=== 1.7.12 2013-01-15
|
||||||
|
|
||||||
|
* Add support for setting a Stripe API version override
|
||||||
|
|
||||||
|
=== 1.7.11 2012-12-30
|
||||||
|
|
||||||
|
* Version bump to cleanup constants and such (github issue #26)
|
||||||
|
|
||||||
|
=== 1.7.10 2012-11-08
|
||||||
|
|
||||||
|
* Add support for updating charge disputes.
|
||||||
|
* Fix bug preventing retrieval of null attributes
|
||||||
|
|
||||||
|
=== 1.7.9 2012-11-08
|
||||||
|
|
||||||
|
* Fix usage under autoloaders such as the one generated by composer
|
||||||
|
(github issue #22)
|
||||||
|
|
||||||
|
=== 1.7.8 2012-10-30
|
||||||
|
* Add support for creating invoices.
|
||||||
|
* Add support for new invoice lines return format
|
||||||
|
* Add support for new list objects
|
||||||
|
|
||||||
|
=== 1.7.7 2012-09-14
|
||||||
|
|
||||||
|
* Get all of the various version numbers in the repo in sync (no other
|
||||||
|
changes)
|
||||||
|
|
||||||
|
=== 1.7.6 2012-08-31
|
||||||
|
|
||||||
|
* Add update and pay methods to Invoice resource
|
||||||
|
|
||||||
|
=== 1.7.5 2012-08-23
|
||||||
|
|
||||||
|
* Change internal function names so that Stripe_SingletonApiRequst is
|
||||||
|
E_STRICT-clean (github issue #16)
|
||||||
|
|
||||||
|
=== 1.7.4 2012-08-21
|
||||||
|
|
||||||
|
* Bugfix so that Stripe objects (e.g. Customer, Charge objects) used
|
||||||
|
in API calls are transparently converted to their object IDs
|
||||||
|
|
||||||
|
=== 1.7.3 2012-08-15
|
||||||
|
|
||||||
|
* Add new Account resource
|
||||||
|
|
||||||
|
=== 1.7.2 2012-06-26
|
||||||
|
|
||||||
|
* Make clearer that you should be including lib/Stripe.php, not
|
||||||
|
test/Stripe.php (github issue #14)
|
||||||
|
|
||||||
|
=== 1.7.1 2012-05-24
|
||||||
|
|
||||||
|
* Add missing argument to Stripe_InvalidRequestError constructor in
|
||||||
|
Stripe_ApiResource::instanceUrl. Fixes a warning when
|
||||||
|
Stripe_ApiResource::instanceUrl is called on a resouce with no ID
|
||||||
|
(github issue #12)
|
||||||
|
|
||||||
|
=== 1.7.0 2012-05-17
|
||||||
|
|
||||||
|
* Support Composer and Packagist (github issue #9)
|
||||||
|
|
||||||
|
* Add new deleteDiscount method to Stripe_Customer
|
||||||
|
|
||||||
|
* Add new Transfer resource
|
||||||
|
|
||||||
|
* Switch from using HTTP Basic auth to Bearer auth. (Note: Stripe will
|
||||||
|
support Basic auth for the indefinite future, but recommends Bearer
|
||||||
|
auth when possible going forward)
|
||||||
|
|
||||||
|
* Numerous test suite improvements
|
||||||
21
vendor/stripe/stripe-php/LICENSE
vendored
Normal file
21
vendor/stripe/stripe-php/LICENSE
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
The MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2010 Stripe
|
||||||
|
|
||||||
|
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.
|
||||||
30
vendor/stripe/stripe-php/README.rdoc
vendored
Normal file
30
vendor/stripe/stripe-php/README.rdoc
vendored
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
= Installation
|
||||||
|
|
||||||
|
Obtain the latest version of the Stripe PHP bindings with:
|
||||||
|
|
||||||
|
git clone https://github.com/stripe/stripe-php
|
||||||
|
|
||||||
|
To get started, add the following to your PHP script:
|
||||||
|
|
||||||
|
require_once("/path/to/stripe-php/lib/Stripe.php");
|
||||||
|
|
||||||
|
Simple usage looks like:
|
||||||
|
|
||||||
|
Stripe::setApiKey('d8e8fca2dc0f896fd7cb4cb0031ba249');
|
||||||
|
$myCard = array('number' => '4242424242424242', 'exp_month' => 5, 'exp_year' => 2015);
|
||||||
|
$charge = Stripe_Charge::create(array('card' => $myCard, 'amount' => 2000, 'currency' => 'usd'));
|
||||||
|
echo $charge;
|
||||||
|
|
||||||
|
= Documentation
|
||||||
|
|
||||||
|
Please see https://stripe.com/api for up-to-date documentation.
|
||||||
|
|
||||||
|
= Tests
|
||||||
|
|
||||||
|
In order to run tests you have to install SimpleTest (http://packagist.org/packages/vierbergenlars/simpletest) via Composer (http://getcomposer.org/) (recommended way):
|
||||||
|
|
||||||
|
composer.phar update --dev
|
||||||
|
|
||||||
|
Run test suite:
|
||||||
|
|
||||||
|
php ./test/Stripe.php
|
||||||
1
vendor/stripe/stripe-php/VERSION
vendored
Normal file
1
vendor/stripe/stripe-php/VERSION
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
1.8.0
|
||||||
27
vendor/stripe/stripe-php/composer.json
vendored
Normal file
27
vendor/stripe/stripe-php/composer.json
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"name": "stripe/stripe-php",
|
||||||
|
"description": "Stripe PHP Library",
|
||||||
|
"keywords": [
|
||||||
|
"stripe",
|
||||||
|
"payment processing",
|
||||||
|
"api"
|
||||||
|
],
|
||||||
|
"homepage": "https://stripe.com/",
|
||||||
|
"license": "MIT",
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Stripe and contributors",
|
||||||
|
"homepage": "https://github.com/stripe/stripe-php/contributors"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.2",
|
||||||
|
"ext-curl": "*"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"vierbergenlars/simpletest": "*"
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"classmap": ["lib/Stripe/"]
|
||||||
|
}
|
||||||
|
}
|
||||||
46
vendor/stripe/stripe-php/lib/Stripe.php
vendored
Normal file
46
vendor/stripe/stripe-php/lib/Stripe.php
vendored
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
// Tested on PHP 5.2, 5.3
|
||||||
|
|
||||||
|
// This snippet (and some of the curl code) due to the Facebook SDK.
|
||||||
|
if (!function_exists('curl_init')) {
|
||||||
|
throw new Exception('Stripe needs the CURL PHP extension.');
|
||||||
|
}
|
||||||
|
if (!function_exists('json_decode')) {
|
||||||
|
throw new Exception('Stripe needs the JSON PHP extension.');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stripe singleton
|
||||||
|
require(dirname(__FILE__) . '/Stripe/Stripe.php');
|
||||||
|
|
||||||
|
// Utilities
|
||||||
|
require(dirname(__FILE__) . '/Stripe/Util.php');
|
||||||
|
require(dirname(__FILE__) . '/Stripe/Util/Set.php');
|
||||||
|
|
||||||
|
// Errors
|
||||||
|
require(dirname(__FILE__) . '/Stripe/Error.php');
|
||||||
|
require(dirname(__FILE__) . '/Stripe/ApiError.php');
|
||||||
|
require(dirname(__FILE__) . '/Stripe/ApiConnectionError.php');
|
||||||
|
require(dirname(__FILE__) . '/Stripe/AuthenticationError.php');
|
||||||
|
require(dirname(__FILE__) . '/Stripe/CardError.php');
|
||||||
|
require(dirname(__FILE__) . '/Stripe/InvalidRequestError.php');
|
||||||
|
|
||||||
|
// Plumbing
|
||||||
|
require(dirname(__FILE__) . '/Stripe/Object.php');
|
||||||
|
require(dirname(__FILE__) . '/Stripe/ApiRequestor.php');
|
||||||
|
require(dirname(__FILE__) . '/Stripe/ApiResource.php');
|
||||||
|
require(dirname(__FILE__) . '/Stripe/SingletonApiResource.php');
|
||||||
|
require(dirname(__FILE__) . '/Stripe/List.php');
|
||||||
|
|
||||||
|
// Stripe API Resources
|
||||||
|
require(dirname(__FILE__) . '/Stripe/Account.php');
|
||||||
|
require(dirname(__FILE__) . '/Stripe/Charge.php');
|
||||||
|
require(dirname(__FILE__) . '/Stripe/Customer.php');
|
||||||
|
require(dirname(__FILE__) . '/Stripe/Invoice.php');
|
||||||
|
require(dirname(__FILE__) . '/Stripe/InvoiceItem.php');
|
||||||
|
require(dirname(__FILE__) . '/Stripe/Plan.php');
|
||||||
|
require(dirname(__FILE__) . '/Stripe/Token.php');
|
||||||
|
require(dirname(__FILE__) . '/Stripe/Coupon.php');
|
||||||
|
require(dirname(__FILE__) . '/Stripe/Event.php');
|
||||||
|
require(dirname(__FILE__) . '/Stripe/Transfer.php');
|
||||||
|
require(dirname(__FILE__) . '/Stripe/Recipient.php');
|
||||||
16
vendor/stripe/stripe-php/lib/Stripe/Account.php
vendored
Normal file
16
vendor/stripe/stripe-php/lib/Stripe/Account.php
vendored
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class Stripe_Account extends Stripe_SingletonApiResource
|
||||||
|
{
|
||||||
|
public static function constructFrom($values, $apiKey=null)
|
||||||
|
{
|
||||||
|
$class = get_class();
|
||||||
|
return self::scopedConstructFrom($class, $values, $apiKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function retrieve($apiKey=null)
|
||||||
|
{
|
||||||
|
$class = get_class();
|
||||||
|
return self::_scopedSingletonRetrieve($class, $apiKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
5
vendor/stripe/stripe-php/lib/Stripe/ApiConnectionError.php
vendored
Normal file
5
vendor/stripe/stripe-php/lib/Stripe/ApiConnectionError.php
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class Stripe_ApiConnectionError extends Stripe_Error
|
||||||
|
{
|
||||||
|
}
|
||||||
5
vendor/stripe/stripe-php/lib/Stripe/ApiError.php
vendored
Normal file
5
vendor/stripe/stripe-php/lib/Stripe/ApiError.php
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class Stripe_ApiError extends Stripe_Error
|
||||||
|
{
|
||||||
|
}
|
||||||
222
vendor/stripe/stripe-php/lib/Stripe/ApiRequestor.php
vendored
Normal file
222
vendor/stripe/stripe-php/lib/Stripe/ApiRequestor.php
vendored
Normal file
@ -0,0 +1,222 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class Stripe_ApiRequestor
|
||||||
|
{
|
||||||
|
public $apiKey;
|
||||||
|
|
||||||
|
public function __construct($apiKey=null)
|
||||||
|
{
|
||||||
|
$this->_apiKey = $apiKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function apiUrl($url='')
|
||||||
|
{
|
||||||
|
$apiBase = Stripe::$apiBase;
|
||||||
|
return "$apiBase$url";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function utf8($value)
|
||||||
|
{
|
||||||
|
if (is_string($value) && mb_detect_encoding($value, "UTF-8", TRUE) != "UTF-8")
|
||||||
|
return utf8_encode($value);
|
||||||
|
else
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function _encodeObjects($d)
|
||||||
|
{
|
||||||
|
if ($d instanceof Stripe_ApiResource) {
|
||||||
|
return self::utf8($d->id);
|
||||||
|
} else if ($d === true) {
|
||||||
|
return 'true';
|
||||||
|
} else if ($d === false) {
|
||||||
|
return 'false';
|
||||||
|
} else if (is_array($d)) {
|
||||||
|
$res = array();
|
||||||
|
foreach ($d as $k => $v)
|
||||||
|
$res[$k] = self::_encodeObjects($v);
|
||||||
|
return $res;
|
||||||
|
} else {
|
||||||
|
return self::utf8($d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function encode($arr, $prefix=null)
|
||||||
|
{
|
||||||
|
if (!is_array($arr))
|
||||||
|
return $arr;
|
||||||
|
|
||||||
|
$r = array();
|
||||||
|
foreach ($arr as $k => $v) {
|
||||||
|
if (is_null($v))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ($prefix && $k && !is_int($k))
|
||||||
|
$k = $prefix."[".$k."]";
|
||||||
|
else if ($prefix)
|
||||||
|
$k = $prefix."[]";
|
||||||
|
|
||||||
|
if (is_array($v)) {
|
||||||
|
$r[] = self::encode($v, $k, true);
|
||||||
|
} else {
|
||||||
|
$r[] = urlencode($k)."=".urlencode($v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return implode("&", $r);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function request($meth, $url, $params=null)
|
||||||
|
{
|
||||||
|
if (!$params)
|
||||||
|
$params = array();
|
||||||
|
list($rbody, $rcode, $myApiKey) = $this->_requestRaw($meth, $url, $params);
|
||||||
|
$resp = $this->_interpretResponse($rbody, $rcode);
|
||||||
|
return array($resp, $myApiKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleApiError($rbody, $rcode, $resp)
|
||||||
|
{
|
||||||
|
if (!is_array($resp) || !isset($resp['error']))
|
||||||
|
throw new Stripe_ApiError("Invalid response object from API: $rbody (HTTP response code was $rcode)", $rcode, $rbody, $resp);
|
||||||
|
$error = $resp['error'];
|
||||||
|
switch ($rcode) {
|
||||||
|
case 400:
|
||||||
|
case 404:
|
||||||
|
throw new Stripe_InvalidRequestError(isset($error['message']) ? $error['message'] : null,
|
||||||
|
isset($error['param']) ? $error['param'] : null,
|
||||||
|
$rcode, $rbody, $resp);
|
||||||
|
case 401:
|
||||||
|
throw new Stripe_AuthenticationError(isset($error['message']) ? $error['message'] : null, $rcode, $rbody, $resp);
|
||||||
|
case 402:
|
||||||
|
throw new Stripe_CardError(isset($error['message']) ? $error['message'] : null,
|
||||||
|
isset($error['param']) ? $error['param'] : null,
|
||||||
|
isset($error['code']) ? $error['code'] : null,
|
||||||
|
$rcode, $rbody, $resp);
|
||||||
|
default:
|
||||||
|
throw new Stripe_ApiError(isset($error['message']) ? $error['message'] : null, $rcode, $rbody, $resp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _requestRaw($meth, $url, $params)
|
||||||
|
{
|
||||||
|
$myApiKey = $this->_apiKey;
|
||||||
|
if (!$myApiKey)
|
||||||
|
$myApiKey = Stripe::$apiKey;
|
||||||
|
if (!$myApiKey)
|
||||||
|
throw new Stripe_AuthenticationError('No API key provided. (HINT: set your API key using "Stripe::setApiKey(<API-KEY>)". You can generate API keys from the Stripe web interface. See https://stripe.com/api for details, or email support@stripe.com if you have any questions.');
|
||||||
|
|
||||||
|
$absUrl = $this->apiUrl($url);
|
||||||
|
$params = self::_encodeObjects($params);
|
||||||
|
$langVersion = phpversion();
|
||||||
|
$uname = php_uname();
|
||||||
|
$ua = array('bindings_version' => Stripe::VERSION,
|
||||||
|
'lang' => 'php',
|
||||||
|
'lang_version' => $langVersion,
|
||||||
|
'publisher' => 'stripe',
|
||||||
|
'uname' => $uname);
|
||||||
|
$headers = array('X-Stripe-Client-User-Agent: ' . json_encode($ua),
|
||||||
|
'User-Agent: Stripe/v1 PhpBindings/' . Stripe::VERSION,
|
||||||
|
'Authorization: Bearer ' . $myApiKey);
|
||||||
|
if (Stripe::$apiVersion)
|
||||||
|
$headers[] = 'Stripe-Version: ' . Stripe::$apiVersion;
|
||||||
|
list($rbody, $rcode) = $this->_curlRequest($meth, $absUrl, $headers, $params);
|
||||||
|
return array($rbody, $rcode, $myApiKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _interpretResponse($rbody, $rcode)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$resp = json_decode($rbody, true);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
throw new Stripe_ApiError("Invalid response body from API: $rbody (HTTP response code was $rcode)", $rcode, $rbody);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($rcode < 200 || $rcode >= 300) {
|
||||||
|
$this->handleApiError($rbody, $rcode, $resp);
|
||||||
|
}
|
||||||
|
return $resp;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function _curlRequest($meth, $absUrl, $headers, $params)
|
||||||
|
{
|
||||||
|
$curl = curl_init();
|
||||||
|
$meth = strtolower($meth);
|
||||||
|
$opts = array();
|
||||||
|
if ($meth == 'get') {
|
||||||
|
$opts[CURLOPT_HTTPGET] = 1;
|
||||||
|
if (count($params) > 0) {
|
||||||
|
$encoded = self::encode($params);
|
||||||
|
$absUrl = "$absUrl?$encoded";
|
||||||
|
}
|
||||||
|
} else if ($meth == 'post') {
|
||||||
|
$opts[CURLOPT_POST] = 1;
|
||||||
|
$opts[CURLOPT_POSTFIELDS] = self::encode($params);
|
||||||
|
} else if ($meth == 'delete') {
|
||||||
|
$opts[CURLOPT_CUSTOMREQUEST] = 'DELETE';
|
||||||
|
if (count($params) > 0) {
|
||||||
|
$encoded = self::encode($params);
|
||||||
|
$absUrl = "$absUrl?$encoded";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new Stripe_ApiError("Unrecognized method $meth");
|
||||||
|
}
|
||||||
|
|
||||||
|
$absUrl = self::utf8($absUrl);
|
||||||
|
$opts[CURLOPT_URL] = $absUrl;
|
||||||
|
$opts[CURLOPT_RETURNTRANSFER] = true;
|
||||||
|
$opts[CURLOPT_CONNECTTIMEOUT] = 30;
|
||||||
|
$opts[CURLOPT_TIMEOUT] = 80;
|
||||||
|
$opts[CURLOPT_RETURNTRANSFER] = true;
|
||||||
|
$opts[CURLOPT_HTTPHEADER] = $headers;
|
||||||
|
if (!Stripe::$verifySslCerts)
|
||||||
|
$opts[CURLOPT_SSL_VERIFYPEER] = false;
|
||||||
|
|
||||||
|
curl_setopt_array($curl, $opts);
|
||||||
|
$rbody = curl_exec($curl);
|
||||||
|
|
||||||
|
$errno = curl_errno($curl);
|
||||||
|
if ($errno == CURLE_SSL_CACERT ||
|
||||||
|
$errno == CURLE_SSL_PEER_CERTIFICATE ||
|
||||||
|
$errno == 77 // CURLE_SSL_CACERT_BADFILE (constant not defined in PHP though)
|
||||||
|
) {
|
||||||
|
array_push($headers, 'X-Stripe-Client-Info: {"ca":"using Stripe-supplied CA bundle"}');
|
||||||
|
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
|
||||||
|
curl_setopt($curl, CURLOPT_CAINFO,
|
||||||
|
dirname(__FILE__) . '/../data/ca-certificates.crt');
|
||||||
|
$rbody = curl_exec($curl);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($rbody === false) {
|
||||||
|
$errno = curl_errno($curl);
|
||||||
|
$message = curl_error($curl);
|
||||||
|
curl_close($curl);
|
||||||
|
$this->handleCurlError($errno, $message);
|
||||||
|
}
|
||||||
|
|
||||||
|
$rcode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
|
||||||
|
curl_close($curl);
|
||||||
|
return array($rbody, $rcode);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function handleCurlError($errno, $message)
|
||||||
|
{
|
||||||
|
$apiBase = Stripe::$apiBase;
|
||||||
|
switch ($errno) {
|
||||||
|
case CURLE_COULDNT_CONNECT:
|
||||||
|
case CURLE_COULDNT_RESOLVE_HOST:
|
||||||
|
case CURLE_OPERATION_TIMEOUTED:
|
||||||
|
$msg = "Could not connect to Stripe ($apiBase). Please check your internet connection and try again. If this problem persists, you should check Stripe's service status at https://twitter.com/stripestatus, or let us know at support@stripe.com.";
|
||||||
|
break;
|
||||||
|
case CURLE_SSL_CACERT:
|
||||||
|
case CURLE_SSL_PEER_CERTIFICATE:
|
||||||
|
$msg = "Could not verify Stripe's SSL certificate. Please make sure that your network is not intercepting certificates. (Try going to $apiBase in your browser.) If this problem persists, let us know at support@stripe.com.";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$msg = "Unexpected error communicating with Stripe. If this problem persists, let us know at support@stripe.com.";
|
||||||
|
}
|
||||||
|
|
||||||
|
$msg .= "\n\n(Network error [errno $errno]: $message)";
|
||||||
|
throw new Stripe_ApiConnectionError($msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
104
vendor/stripe/stripe-php/lib/Stripe/ApiResource.php
vendored
Normal file
104
vendor/stripe/stripe-php/lib/Stripe/ApiResource.php
vendored
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
abstract class Stripe_ApiResource extends Stripe_Object
|
||||||
|
{
|
||||||
|
protected static function _scopedRetrieve($class, $id, $apiKey=null)
|
||||||
|
{
|
||||||
|
$instance = new $class($id, $apiKey);
|
||||||
|
$instance->refresh();
|
||||||
|
return $instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function refresh()
|
||||||
|
{
|
||||||
|
$requestor = new Stripe_ApiRequestor($this->_apiKey);
|
||||||
|
$url = $this->instanceUrl();
|
||||||
|
|
||||||
|
list($response, $apiKey) = $requestor->request('get', $url, $this->_retrieveOptions);
|
||||||
|
$this->refreshFrom($response, $apiKey);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function className($class)
|
||||||
|
{
|
||||||
|
// Useful for namespaces: Foo\Stripe_Charge
|
||||||
|
if ($postfix = strrchr($class, '\\'))
|
||||||
|
$class = substr($postfix, 1);
|
||||||
|
if (substr($class, 0, strlen('Stripe')) == 'Stripe')
|
||||||
|
$class = substr($class, strlen('Stripe'));
|
||||||
|
$class = str_replace('_', '', $class);
|
||||||
|
$name = urlencode($class);
|
||||||
|
$name = strtolower($name);
|
||||||
|
return $name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function classUrl($class)
|
||||||
|
{
|
||||||
|
$base = self::className($class);
|
||||||
|
return "/v1/${base}s";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function instanceUrl()
|
||||||
|
{
|
||||||
|
$id = $this['id'];
|
||||||
|
$class = get_class($this);
|
||||||
|
if (!$id) {
|
||||||
|
throw new Stripe_InvalidRequestError("Could not determine which URL to request: $class instance has invalid ID: $id", null);
|
||||||
|
}
|
||||||
|
$id = Stripe_ApiRequestor::utf8($id);
|
||||||
|
$base = self::classUrl($class);
|
||||||
|
$extn = urlencode($id);
|
||||||
|
return "$base/$extn";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function _validateCall($method, $params=null, $apiKey=null)
|
||||||
|
{
|
||||||
|
if ($params && !is_array($params))
|
||||||
|
throw new Stripe_Error("You must pass an array as the first argument to Stripe API method calls. (HINT: an example call to create a charge would be: \"StripeCharge::create(array('amount' => 100, 'currency' => 'usd', 'card' => array('number' => 4242424242424242, 'exp_month' => 5, 'exp_year' => 2015)))\")");
|
||||||
|
if ($apiKey && !is_string($apiKey))
|
||||||
|
throw new Stripe_Error('The second argument to Stripe API method calls is an optional per-request apiKey, which must be a string. (HINT: you can set a global apiKey by "Stripe::setApiKey(<apiKey>)")');
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static function _scopedAll($class, $params=null, $apiKey=null)
|
||||||
|
{
|
||||||
|
self::_validateCall('all', $params, $apiKey);
|
||||||
|
$requestor = new Stripe_ApiRequestor($apiKey);
|
||||||
|
$url = self::classUrl($class);
|
||||||
|
list($response, $apiKey) = $requestor->request('get', $url, $params);
|
||||||
|
return Stripe_Util::convertToStripeObject($response, $apiKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static function _scopedCreate($class, $params=null, $apiKey=null)
|
||||||
|
{
|
||||||
|
self::_validateCall('create', $params, $apiKey);
|
||||||
|
$requestor = new Stripe_ApiRequestor($apiKey);
|
||||||
|
$url = self::classUrl($class);
|
||||||
|
list($response, $apiKey) = $requestor->request('post', $url, $params);
|
||||||
|
return Stripe_Util::convertToStripeObject($response, $apiKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function _scopedSave($class)
|
||||||
|
{
|
||||||
|
self::_validateCall('save');
|
||||||
|
if ($this->_unsavedValues) {
|
||||||
|
$requestor = new Stripe_ApiRequestor($this->_apiKey);
|
||||||
|
$params = array();
|
||||||
|
foreach ($this->_unsavedValues->toArray() as $k)
|
||||||
|
$params[$k] = $this->$k;
|
||||||
|
$url = $this->instanceUrl();
|
||||||
|
list($response, $apiKey) = $requestor->request('post', $url, $params);
|
||||||
|
$this->refreshFrom($response, $apiKey);
|
||||||
|
}
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function _scopedDelete($class, $params=null)
|
||||||
|
{
|
||||||
|
self::_validateCall('delete');
|
||||||
|
$requestor = new Stripe_ApiRequestor($this->_apiKey);
|
||||||
|
$url = $this->instanceUrl();
|
||||||
|
list($response, $apiKey) = $requestor->request('delete', $url, $params);
|
||||||
|
$this->refreshFrom($response, $apiKey);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
||||||
5
vendor/stripe/stripe-php/lib/Stripe/AuthenticationError.php
vendored
Normal file
5
vendor/stripe/stripe-php/lib/Stripe/AuthenticationError.php
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class Stripe_AuthenticationError extends Stripe_Error
|
||||||
|
{
|
||||||
|
}
|
||||||
11
vendor/stripe/stripe-php/lib/Stripe/CardError.php
vendored
Normal file
11
vendor/stripe/stripe-php/lib/Stripe/CardError.php
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class Stripe_CardError extends Stripe_Error
|
||||||
|
{
|
||||||
|
public function __construct($message, $param, $code, $http_status=null, $http_body=null, $json_body=null)
|
||||||
|
{
|
||||||
|
parent::__construct($message, $http_status, $http_body, $json_body);
|
||||||
|
$this->param = $param;
|
||||||
|
$this->code = $code;
|
||||||
|
}
|
||||||
|
}
|
||||||
61
vendor/stripe/stripe-php/lib/Stripe/Charge.php
vendored
Normal file
61
vendor/stripe/stripe-php/lib/Stripe/Charge.php
vendored
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class Stripe_Charge extends Stripe_ApiResource
|
||||||
|
{
|
||||||
|
public static function constructFrom($values, $apiKey=null)
|
||||||
|
{
|
||||||
|
$class = get_class();
|
||||||
|
return self::scopedConstructFrom($class, $values, $apiKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function retrieve($id, $apiKey=null)
|
||||||
|
{
|
||||||
|
$class = get_class();
|
||||||
|
return self::_scopedRetrieve($class, $id, $apiKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function all($params=null, $apiKey=null)
|
||||||
|
{
|
||||||
|
$class = get_class();
|
||||||
|
return self::_scopedAll($class, $params, $apiKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function create($params=null, $apiKey=null)
|
||||||
|
{
|
||||||
|
$class = get_class();
|
||||||
|
return self::_scopedCreate($class, $params, $apiKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function save()
|
||||||
|
{
|
||||||
|
$class = get_class();
|
||||||
|
return self::_scopedSave($class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function refund($params=null)
|
||||||
|
{
|
||||||
|
$requestor = new Stripe_ApiRequestor($this->_apiKey);
|
||||||
|
$url = $this->instanceUrl() . '/refund';
|
||||||
|
list($response, $apiKey) = $requestor->request('post', $url, $params);
|
||||||
|
$this->refreshFrom($response, $apiKey);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function capture($params=null)
|
||||||
|
{
|
||||||
|
$requestor = new Stripe_ApiRequestor($this->_apiKey);
|
||||||
|
$url = $this->instanceUrl() . '/capture';
|
||||||
|
list($response, $apiKey) = $requestor->request('post', $url, $params);
|
||||||
|
$this->refreshFrom($response, $apiKey);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updateDispute($params=null)
|
||||||
|
{
|
||||||
|
$requestor = new Stripe_ApiRequestor($this->_apiKey);
|
||||||
|
$url = $this->instanceUrl() . '/dispute';
|
||||||
|
list($response, $apiKey) = $requestor->request('post', $url, $params);
|
||||||
|
$this->refreshFrom(array('dispute' => $response), $apiKey, true);
|
||||||
|
return $this->dispute;
|
||||||
|
}
|
||||||
|
}
|
||||||
34
vendor/stripe/stripe-php/lib/Stripe/Coupon.php
vendored
Normal file
34
vendor/stripe/stripe-php/lib/Stripe/Coupon.php
vendored
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class Stripe_Coupon extends Stripe_ApiResource
|
||||||
|
{
|
||||||
|
public static function constructFrom($values, $apiKey=null)
|
||||||
|
{
|
||||||
|
$class = get_class();
|
||||||
|
return self::scopedConstructFrom($class, $values, $apiKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function retrieve($id, $apiKey=null)
|
||||||
|
{
|
||||||
|
$class = get_class();
|
||||||
|
return self::_scopedRetrieve($class, $id, $apiKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function create($params=null, $apiKey=null)
|
||||||
|
{
|
||||||
|
$class = get_class();
|
||||||
|
return self::_scopedCreate($class, $params, $apiKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function delete($params=null)
|
||||||
|
{
|
||||||
|
$class = get_class();
|
||||||
|
return self::_scopedDelete($class, $params);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function all($params=null, $apiKey=null)
|
||||||
|
{
|
||||||
|
$class = get_class();
|
||||||
|
return self::_scopedAll($class, $params, $apiKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
102
vendor/stripe/stripe-php/lib/Stripe/Customer.php
vendored
Normal file
102
vendor/stripe/stripe-php/lib/Stripe/Customer.php
vendored
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class Stripe_Customer extends Stripe_ApiResource
|
||||||
|
{
|
||||||
|
public static function constructFrom($values, $apiKey=null)
|
||||||
|
{
|
||||||
|
$class = get_class();
|
||||||
|
return self::scopedConstructFrom($class, $values, $apiKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function retrieve($id, $apiKey=null)
|
||||||
|
{
|
||||||
|
$class = get_class();
|
||||||
|
return self::_scopedRetrieve($class, $id, $apiKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function all($params=null, $apiKey=null)
|
||||||
|
{
|
||||||
|
$class = get_class();
|
||||||
|
return self::_scopedAll($class, $params, $apiKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function create($params=null, $apiKey=null)
|
||||||
|
{
|
||||||
|
$class = get_class();
|
||||||
|
return self::_scopedCreate($class, $params, $apiKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function save()
|
||||||
|
{
|
||||||
|
$class = get_class();
|
||||||
|
return self::_scopedSave($class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function delete($params=null)
|
||||||
|
{
|
||||||
|
$class = get_class();
|
||||||
|
return self::_scopedDelete($class, $params);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addInvoiceItem($params=null)
|
||||||
|
{
|
||||||
|
if (!$params)
|
||||||
|
$params = array();
|
||||||
|
$params['customer'] = $this->id;
|
||||||
|
$ii = Stripe_InvoiceItem::create($params, $this->_apiKey);
|
||||||
|
return $ii;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function invoices($params=null)
|
||||||
|
{
|
||||||
|
if (!$params)
|
||||||
|
$params = array();
|
||||||
|
$params['customer'] = $this->id;
|
||||||
|
$invoices = Stripe_Invoice::all($params, $this->_apiKey);
|
||||||
|
return $invoices;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function invoiceItems($params=null)
|
||||||
|
{
|
||||||
|
if (!$params)
|
||||||
|
$params = array();
|
||||||
|
$params['customer'] = $this->id;
|
||||||
|
$iis = Stripe_InvoiceItem::all($params, $this->_apiKey);
|
||||||
|
return $iis;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function charges($params=null)
|
||||||
|
{
|
||||||
|
if (!$params)
|
||||||
|
$params = array();
|
||||||
|
$params['customer'] = $this->id;
|
||||||
|
$charges = Stripe_Charge::all($params, $this->_apiKey);
|
||||||
|
return $charges;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updateSubscription($params=null)
|
||||||
|
{
|
||||||
|
$requestor = new Stripe_ApiRequestor($this->_apiKey);
|
||||||
|
$url = $this->instanceUrl() . '/subscription';
|
||||||
|
list($response, $apiKey) = $requestor->request('post', $url, $params);
|
||||||
|
$this->refreshFrom(array('subscription' => $response), $apiKey, true);
|
||||||
|
return $this->subscription;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function cancelSubscription($params=null)
|
||||||
|
{
|
||||||
|
$requestor = new Stripe_ApiRequestor($this->_apiKey);
|
||||||
|
$url = $this->instanceUrl() . '/subscription';
|
||||||
|
list($response, $apiKey) = $requestor->request('delete', $url, $params);
|
||||||
|
$this->refreshFrom(array('subscription' => $response), $apiKey, true);
|
||||||
|
return $this->subscription;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function deleteDiscount()
|
||||||
|
{
|
||||||
|
$requestor = new Stripe_ApiRequestor($this->_apiKey);
|
||||||
|
$url = $this->instanceUrl() . '/discount';
|
||||||
|
list($response, $apiKey) = $requestor->request('delete', $url);
|
||||||
|
$this->refreshFrom(array('discount' => null), $apiKey, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
27
vendor/stripe/stripe-php/lib/Stripe/Error.php
vendored
Normal file
27
vendor/stripe/stripe-php/lib/Stripe/Error.php
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class Stripe_Error extends Exception
|
||||||
|
{
|
||||||
|
public function __construct($message=null, $http_status=null, $http_body=null, $json_body=null)
|
||||||
|
{
|
||||||
|
parent::__construct($message);
|
||||||
|
$this->http_status = $http_status;
|
||||||
|
$this->http_body = $http_body;
|
||||||
|
$this->json_body = $json_body;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHttpStatus()
|
||||||
|
{
|
||||||
|
return $this->http_status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getHttpBody()
|
||||||
|
{
|
||||||
|
return $this->http_body;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getJsonBody()
|
||||||
|
{
|
||||||
|
return $this->json_body;
|
||||||
|
}
|
||||||
|
}
|
||||||
22
vendor/stripe/stripe-php/lib/Stripe/Event.php
vendored
Normal file
22
vendor/stripe/stripe-php/lib/Stripe/Event.php
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class Stripe_Event extends Stripe_ApiResource
|
||||||
|
{
|
||||||
|
public static function constructFrom($values, $apiKey=null)
|
||||||
|
{
|
||||||
|
$class = get_class();
|
||||||
|
return self::scopedConstructFrom($class, $values, $apiKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function retrieve($id, $apiKey=null)
|
||||||
|
{
|
||||||
|
$class = get_class();
|
||||||
|
return self::_scopedRetrieve($class, $id, $apiKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function all($params=null, $apiKey=null)
|
||||||
|
{
|
||||||
|
$class = get_class();
|
||||||
|
return self::_scopedAll($class, $params, $apiKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
10
vendor/stripe/stripe-php/lib/Stripe/InvalidRequestError.php
vendored
Normal file
10
vendor/stripe/stripe-php/lib/Stripe/InvalidRequestError.php
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class Stripe_InvalidRequestError extends Stripe_Error
|
||||||
|
{
|
||||||
|
public function __construct($message, $param, $http_status=null, $http_body=null, $json_body=null)
|
||||||
|
{
|
||||||
|
parent::__construct($message, $http_status, $http_body, $json_body);
|
||||||
|
$this->param = $param;
|
||||||
|
}
|
||||||
|
}
|
||||||
51
vendor/stripe/stripe-php/lib/Stripe/Invoice.php
vendored
Normal file
51
vendor/stripe/stripe-php/lib/Stripe/Invoice.php
vendored
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class Stripe_Invoice extends Stripe_ApiResource
|
||||||
|
{
|
||||||
|
public static function constructFrom($values, $apiKey=null)
|
||||||
|
{
|
||||||
|
$class = get_class();
|
||||||
|
return self::scopedConstructFrom($class, $values, $apiKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function create($params=null, $apiKey=null)
|
||||||
|
{
|
||||||
|
$class = get_class();
|
||||||
|
return self::_scopedCreate($class, $params, $apiKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function retrieve($id, $apiKey=null)
|
||||||
|
{
|
||||||
|
$class = get_class();
|
||||||
|
return self::_scopedRetrieve($class, $id, $apiKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function all($params=null, $apiKey=null)
|
||||||
|
{
|
||||||
|
$class = get_class();
|
||||||
|
return self::_scopedAll($class, $params, $apiKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function upcoming($params=null, $apiKey=null)
|
||||||
|
{
|
||||||
|
$requestor = new Stripe_ApiRequestor($apiKey);
|
||||||
|
$url = self::classUrl(get_class()) . '/upcoming';
|
||||||
|
list($response, $apiKey) = $requestor->request('get', $url, $params);
|
||||||
|
return Stripe_Util::convertToStripeObject($response, $apiKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function save()
|
||||||
|
{
|
||||||
|
$class = get_class();
|
||||||
|
return self::_scopedSave($class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function pay()
|
||||||
|
{
|
||||||
|
$requestor = new Stripe_ApiRequestor($this->_apiKey);
|
||||||
|
$url = $this->instanceUrl() . '/pay';
|
||||||
|
list($response, $apiKey) = $requestor->request('post', $url);
|
||||||
|
$this->refreshFrom($response, $apiKey);
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
}
|
||||||
40
vendor/stripe/stripe-php/lib/Stripe/InvoiceItem.php
vendored
Normal file
40
vendor/stripe/stripe-php/lib/Stripe/InvoiceItem.php
vendored
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class Stripe_InvoiceItem extends Stripe_ApiResource
|
||||||
|
{
|
||||||
|
public static function constructFrom($values, $apiKey=null)
|
||||||
|
{
|
||||||
|
$class = get_class();
|
||||||
|
return self::scopedConstructFrom($class, $values, $apiKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function retrieve($id, $apiKey=null)
|
||||||
|
{
|
||||||
|
$class = get_class();
|
||||||
|
return self::_scopedRetrieve($class, $id, $apiKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function all($params=null, $apiKey=null)
|
||||||
|
{
|
||||||
|
$class = get_class();
|
||||||
|
return self::_scopedAll($class, $params, $apiKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function create($params=null, $apiKey=null)
|
||||||
|
{
|
||||||
|
$class = get_class();
|
||||||
|
return self::_scopedCreate($class, $params, $apiKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function save()
|
||||||
|
{
|
||||||
|
$class = get_class();
|
||||||
|
return self::_scopedSave($class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function delete($params=null)
|
||||||
|
{
|
||||||
|
$class = get_class();
|
||||||
|
return self::_scopedDelete($class, $params);
|
||||||
|
}
|
||||||
|
}
|
||||||
17
vendor/stripe/stripe-php/lib/Stripe/List.php
vendored
Normal file
17
vendor/stripe/stripe-php/lib/Stripe/List.php
vendored
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class Stripe_List extends Stripe_Object
|
||||||
|
{
|
||||||
|
public static function constructFrom($values, $apiKey=null)
|
||||||
|
{
|
||||||
|
$class = get_class();
|
||||||
|
return self::scopedConstructFrom($class, $values, $apiKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function all($params=null)
|
||||||
|
{
|
||||||
|
$requestor = new Stripe_ApiRequestor($this->_apiKey);
|
||||||
|
list($response, $apiKey) = $requestor->request('get', $this['url'], $params);
|
||||||
|
return Stripe_Util::convertToStripeObject($response, $apiKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
155
vendor/stripe/stripe-php/lib/Stripe/Object.php
vendored
Normal file
155
vendor/stripe/stripe-php/lib/Stripe/Object.php
vendored
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class Stripe_Object implements ArrayAccess
|
||||||
|
{
|
||||||
|
public static $_permanentAttributes;
|
||||||
|
|
||||||
|
public static function init()
|
||||||
|
{
|
||||||
|
self::$_permanentAttributes = new Stripe_Util_Set(array('_apiKey', 'id'));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected $_apiKey;
|
||||||
|
protected $_values;
|
||||||
|
protected $_unsavedValues;
|
||||||
|
protected $_transientValues;
|
||||||
|
protected $_retrieveOptions;
|
||||||
|
|
||||||
|
public function __construct($id=null, $apiKey=null)
|
||||||
|
{
|
||||||
|
$this->_apiKey = $apiKey;
|
||||||
|
$this->_values = array();
|
||||||
|
$this->_unsavedValues = new Stripe_Util_Set();
|
||||||
|
$this->_transientValues = new Stripe_Util_Set();
|
||||||
|
|
||||||
|
$this->_retrieveOptions = array();
|
||||||
|
if (is_array($id)) {
|
||||||
|
foreach($id as $key => $value) {
|
||||||
|
if ($key != 'id')
|
||||||
|
$this->_retrieveOptions[$key] = $value;
|
||||||
|
}
|
||||||
|
$id = $id['id'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($id)
|
||||||
|
$this->id = $id;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Standard accessor magic methods
|
||||||
|
public function __set($k, $v)
|
||||||
|
{
|
||||||
|
// TODO: may want to clear from $_transientValues. (Won't be user-visible.)
|
||||||
|
$this->_values[$k] = $v;
|
||||||
|
if (!self::$_permanentAttributes->includes($k))
|
||||||
|
$this->_unsavedValues->add($k);
|
||||||
|
}
|
||||||
|
public function __isset($k)
|
||||||
|
{
|
||||||
|
return isset($this->_values[$k]);
|
||||||
|
}
|
||||||
|
public function __unset($k)
|
||||||
|
{
|
||||||
|
unset($this->_values[$k]);
|
||||||
|
$this->_transientValues->add($k);
|
||||||
|
$this->_unsavedValues->discard($k);
|
||||||
|
}
|
||||||
|
public function __get($k)
|
||||||
|
{
|
||||||
|
if (array_key_exists($k, $this->_values)) {
|
||||||
|
return $this->_values[$k];
|
||||||
|
} else if ($this->_transientValues->includes($k)) {
|
||||||
|
$class = get_class($this);
|
||||||
|
$attrs = join(', ', array_keys($this->_values));
|
||||||
|
error_log("Stripe Notice: Undefined property of $class instance: $k. HINT: The $k attribute was set in the past, however. It was then wiped when refreshing the object with the result returned by Stripe's API, probably as a result of a save(). The attributes currently available on this object are: $attrs");
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
$class = get_class($this);
|
||||||
|
error_log("Stripe Notice: Undefined property of $class instance: $k");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ArrayAccess methods
|
||||||
|
public function offsetSet($k, $v)
|
||||||
|
{
|
||||||
|
$this->$k = $v;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function offsetExists($k)
|
||||||
|
{
|
||||||
|
return array_key_exists($k, $this->_values);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function offsetUnset($k)
|
||||||
|
{
|
||||||
|
unset($this->$k);
|
||||||
|
}
|
||||||
|
public function offsetGet($k)
|
||||||
|
{
|
||||||
|
return array_key_exists($k, $this->_values) ? $this->_values[$k] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This unfortunately needs to be public to be used in Util.php
|
||||||
|
public static function scopedConstructFrom($class, $values, $apiKey=null)
|
||||||
|
{
|
||||||
|
$obj = new $class(isset($values['id']) ? $values['id'] : null, $apiKey);
|
||||||
|
$obj->refreshFrom($values, $apiKey);
|
||||||
|
return $obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function constructFrom($values, $apiKey=null)
|
||||||
|
{
|
||||||
|
$class = get_class();
|
||||||
|
return self::scopedConstructFrom($class, $values, $apiKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function refreshFrom($values, $apiKey, $partial=false)
|
||||||
|
{
|
||||||
|
$this->_apiKey = $apiKey;
|
||||||
|
// Wipe old state before setting new. This is useful for e.g. updating a
|
||||||
|
// customer, where there is no persistent card parameter. Mark those values
|
||||||
|
// which don't persist as transient
|
||||||
|
if ($partial)
|
||||||
|
$removed = new Stripe_Util_Set();
|
||||||
|
else
|
||||||
|
$removed = array_diff(array_keys($this->_values), array_keys($values));
|
||||||
|
|
||||||
|
foreach ($removed as $k) {
|
||||||
|
if (self::$_permanentAttributes->includes($k))
|
||||||
|
continue;
|
||||||
|
unset($this->$k);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($values as $k => $v) {
|
||||||
|
if (self::$_permanentAttributes->includes($k))
|
||||||
|
continue;
|
||||||
|
$this->_values[$k] = Stripe_Util::convertToStripeObject($v, $apiKey);
|
||||||
|
$this->_transientValues->discard($k);
|
||||||
|
$this->_unsavedValues->discard($k);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __toJSON()
|
||||||
|
{
|
||||||
|
if (defined('JSON_PRETTY_PRINT'))
|
||||||
|
return json_encode($this->__toArray(true), JSON_PRETTY_PRINT);
|
||||||
|
else
|
||||||
|
return json_encode($this->__toArray(true));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __toString()
|
||||||
|
{
|
||||||
|
return $this->__toJSON();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __toArray($recursive=false)
|
||||||
|
{
|
||||||
|
if ($recursive)
|
||||||
|
return Stripe_Util::convertStripeObjectToArray($this->_values);
|
||||||
|
else
|
||||||
|
return $this->_values;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Stripe_Object::init();
|
||||||
40
vendor/stripe/stripe-php/lib/Stripe/Plan.php
vendored
Normal file
40
vendor/stripe/stripe-php/lib/Stripe/Plan.php
vendored
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class Stripe_Plan extends Stripe_ApiResource
|
||||||
|
{
|
||||||
|
public static function constructFrom($values, $apiKey=null)
|
||||||
|
{
|
||||||
|
$class = get_class();
|
||||||
|
return self::scopedConstructFrom($class, $values, $apiKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function retrieve($id, $apiKey=null)
|
||||||
|
{
|
||||||
|
$class = get_class();
|
||||||
|
return self::_scopedRetrieve($class, $id, $apiKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function create($params=null, $apiKey=null)
|
||||||
|
{
|
||||||
|
$class = get_class();
|
||||||
|
return self::_scopedCreate($class, $params, $apiKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function delete($params=null)
|
||||||
|
{
|
||||||
|
$class = get_class();
|
||||||
|
return self::_scopedDelete($class, $params);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function save()
|
||||||
|
{
|
||||||
|
$class = get_class();
|
||||||
|
return self::_scopedSave($class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function all($params=null, $apiKey=null)
|
||||||
|
{
|
||||||
|
$class = get_class();
|
||||||
|
return self::_scopedAll($class, $params, $apiKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
50
vendor/stripe/stripe-php/lib/Stripe/Recipient.php
vendored
Normal file
50
vendor/stripe/stripe-php/lib/Stripe/Recipient.php
vendored
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class Stripe_Recipient extends Stripe_ApiResource
|
||||||
|
{
|
||||||
|
public static function constructFrom($values, $apiKey=null)
|
||||||
|
{
|
||||||
|
$class = get_class();
|
||||||
|
return self::scopedConstructFrom($class, $values, $apiKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function retrieve($id, $apiKey=null)
|
||||||
|
{
|
||||||
|
$class = get_class();
|
||||||
|
return self::_scopedRetrieve($class, $id, $apiKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function all($params=null, $apiKey=null)
|
||||||
|
{
|
||||||
|
$class = get_class();
|
||||||
|
return self::_scopedAll($class, $params, $apiKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function create($params=null, $apiKey=null)
|
||||||
|
{
|
||||||
|
$class = get_class();
|
||||||
|
return self::_scopedCreate($class, $params, $apiKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function save()
|
||||||
|
{
|
||||||
|
$class = get_class();
|
||||||
|
return self::_scopedSave($class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function delete($params=null)
|
||||||
|
{
|
||||||
|
$class = get_class();
|
||||||
|
return self::_scopedDelete($class, $params);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function transfers($params=null)
|
||||||
|
{
|
||||||
|
if (!$params)
|
||||||
|
$params = array();
|
||||||
|
$params['recipient'] = $this->id;
|
||||||
|
$transfers = Stripe_Transfer::all($params, $this->_apiKey);
|
||||||
|
return $transfers;
|
||||||
|
}
|
||||||
|
}
|
||||||
24
vendor/stripe/stripe-php/lib/Stripe/SingletonApiResource.php
vendored
Normal file
24
vendor/stripe/stripe-php/lib/Stripe/SingletonApiResource.php
vendored
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
abstract class Stripe_SingletonApiResource extends Stripe_ApiResource
|
||||||
|
{
|
||||||
|
protected static function _scopedSingletonRetrieve($class, $apiKey=null)
|
||||||
|
{
|
||||||
|
$instance = new $class(null, $apiKey);
|
||||||
|
$instance->refresh();
|
||||||
|
return $instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function classUrl($class)
|
||||||
|
{
|
||||||
|
$base = self::className($class);
|
||||||
|
return "/v1/${base}";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function instanceUrl()
|
||||||
|
{
|
||||||
|
$class = get_class($this);
|
||||||
|
$base = self::classUrl($class);
|
||||||
|
return "$base";
|
||||||
|
}
|
||||||
|
}
|
||||||
38
vendor/stripe/stripe-php/lib/Stripe/Stripe.php
vendored
Normal file
38
vendor/stripe/stripe-php/lib/Stripe/Stripe.php
vendored
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
abstract class Stripe
|
||||||
|
{
|
||||||
|
public static $apiKey;
|
||||||
|
public static $apiBase = 'https://api.stripe.com';
|
||||||
|
public static $apiVersion = null;
|
||||||
|
public static $verifySslCerts = true;
|
||||||
|
const VERSION = '1.8.0';
|
||||||
|
|
||||||
|
public static function getApiKey()
|
||||||
|
{
|
||||||
|
return self::$apiKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function setApiKey($apiKey)
|
||||||
|
{
|
||||||
|
self::$apiKey = $apiKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getApiVersion()
|
||||||
|
{
|
||||||
|
return self::$apiVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function setApiVersion($apiVersion)
|
||||||
|
{
|
||||||
|
self::$apiVersion = $apiVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function getVerifySslCerts() {
|
||||||
|
return self::$verifySslCerts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function setVerifySslCerts($verify) {
|
||||||
|
self::$verifySslCerts = $verify;
|
||||||
|
}
|
||||||
|
}
|
||||||
22
vendor/stripe/stripe-php/lib/Stripe/Token.php
vendored
Normal file
22
vendor/stripe/stripe-php/lib/Stripe/Token.php
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class Stripe_Token extends Stripe_ApiResource
|
||||||
|
{
|
||||||
|
public static function constructFrom($values, $apiKey=null)
|
||||||
|
{
|
||||||
|
$class = get_class();
|
||||||
|
return self::scopedConstructFrom($class, $values, $apiKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function retrieve($id, $apiKey=null)
|
||||||
|
{
|
||||||
|
$class = get_class();
|
||||||
|
return self::_scopedRetrieve($class, $id, $apiKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function create($params=null, $apiKey=null)
|
||||||
|
{
|
||||||
|
$class = get_class();
|
||||||
|
return self::_scopedCreate($class, $params, $apiKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
30
vendor/stripe/stripe-php/lib/Stripe/Transfer.php
vendored
Normal file
30
vendor/stripe/stripe-php/lib/Stripe/Transfer.php
vendored
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class Stripe_Transfer extends Stripe_ApiResource
|
||||||
|
{
|
||||||
|
public static function constructFrom($values, $apiKey=null)
|
||||||
|
{
|
||||||
|
$class = get_class();
|
||||||
|
return self::scopedConstructFrom($class, $values, $apiKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function retrieve($id, $apiKey=null)
|
||||||
|
{
|
||||||
|
$class = get_class();
|
||||||
|
return self::_scopedRetrieve($class, $id, $apiKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function all($params=null, $apiKey=null)
|
||||||
|
{
|
||||||
|
$class = get_class();
|
||||||
|
return self::_scopedAll($class, $params, $apiKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function create($params=null, $apiKey=null)
|
||||||
|
{
|
||||||
|
$class = get_class();
|
||||||
|
return self::_scopedCreate($class, $params, $apiKey);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
66
vendor/stripe/stripe-php/lib/Stripe/Util.php
vendored
Normal file
66
vendor/stripe/stripe-php/lib/Stripe/Util.php
vendored
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
abstract class Stripe_Util
|
||||||
|
{
|
||||||
|
public static function isList($array)
|
||||||
|
{
|
||||||
|
if (!is_array($array))
|
||||||
|
return false;
|
||||||
|
// TODO: this isn't actually correct in general, but it's correct given Stripe's responses
|
||||||
|
foreach (array_keys($array) as $k) {
|
||||||
|
if (!is_numeric($k))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function convertStripeObjectToArray($values)
|
||||||
|
{
|
||||||
|
$results = array();
|
||||||
|
foreach ($values as $k => $v) {
|
||||||
|
// FIXME: this is an encapsulation violation
|
||||||
|
if (Stripe_Object::$_permanentAttributes->includes($k)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ($v instanceof Stripe_Object) {
|
||||||
|
$results[$k] = $v->__toArray(true);
|
||||||
|
}
|
||||||
|
else if (is_array($v)) {
|
||||||
|
$results[$k] = self::convertStripeObjectToArray($v);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$results[$k] = $v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $results;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function convertToStripeObject($resp, $apiKey)
|
||||||
|
{
|
||||||
|
$types = array(
|
||||||
|
'charge' => 'Stripe_Charge',
|
||||||
|
'customer' => 'Stripe_Customer',
|
||||||
|
'list' => 'Stripe_List',
|
||||||
|
'invoice' => 'Stripe_Invoice',
|
||||||
|
'invoiceitem' => 'Stripe_InvoiceItem',
|
||||||
|
'event' => 'Stripe_Event',
|
||||||
|
'transfer' => 'Stripe_Transfer',
|
||||||
|
'plan' => 'Stripe_Plan',
|
||||||
|
'recipient' => 'Stripe_Recipient'
|
||||||
|
);
|
||||||
|
if (self::isList($resp)) {
|
||||||
|
$mapped = array();
|
||||||
|
foreach ($resp as $i)
|
||||||
|
array_push($mapped, self::convertToStripeObject($i, $apiKey));
|
||||||
|
return $mapped;
|
||||||
|
} else if (is_array($resp)) {
|
||||||
|
if (isset($resp['object']) && is_string($resp['object']) && isset($types[$resp['object']]))
|
||||||
|
$class = $types[$resp['object']];
|
||||||
|
else
|
||||||
|
$class = 'Stripe_Object';
|
||||||
|
return Stripe_Object::scopedConstructFrom($class, $resp, $apiKey);
|
||||||
|
} else {
|
||||||
|
return $resp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
34
vendor/stripe/stripe-php/lib/Stripe/Util/Set.php
vendored
Normal file
34
vendor/stripe/stripe-php/lib/Stripe/Util/Set.php
vendored
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class Stripe_Util_Set
|
||||||
|
{
|
||||||
|
private $_elts;
|
||||||
|
|
||||||
|
public function __construct($members=array())
|
||||||
|
{
|
||||||
|
$this->_elts = array();
|
||||||
|
foreach ($members as $item)
|
||||||
|
$this->_elts[$item] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function includes($elt)
|
||||||
|
{
|
||||||
|
return isset($this->_elts[$elt]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function add($elt)
|
||||||
|
{
|
||||||
|
$this->_elts[$elt] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function discard($elt)
|
||||||
|
{
|
||||||
|
unset($this->_elts[$elt]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: make Set support foreach
|
||||||
|
public function toArray()
|
||||||
|
{
|
||||||
|
return array_keys($this->_elts);
|
||||||
|
}
|
||||||
|
}
|
||||||
3918
vendor/stripe/stripe-php/lib/data/ca-certificates.crt
vendored
Normal file
3918
vendor/stripe/stripe-php/lib/data/ca-certificates.crt
vendored
Normal file
File diff suppressed because it is too large
Load Diff
53
vendor/stripe/stripe-php/test/Stripe.php
vendored
Normal file
53
vendor/stripe/stripe-php/test/Stripe.php
vendored
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
echo "Running the Stripe PHP bindings test suite.\n".
|
||||||
|
"If you're trying to use the Stripe PHP bindings you'll probably want ".
|
||||||
|
"to require('lib/Stripe.php'); instead of this file\n";
|
||||||
|
|
||||||
|
function authorizeFromEnv()
|
||||||
|
{
|
||||||
|
$apiKey = getenv('STRIPE_API_KEY');
|
||||||
|
if (!$apiKey)
|
||||||
|
$apiKey = "tGN0bIwXnHdwOa85VABjPdSn8nWY7G7I";
|
||||||
|
Stripe::setApiKey($apiKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
$ok = @include_once(dirname(__FILE__).'/simpletest/autorun.php');
|
||||||
|
if (!$ok) {
|
||||||
|
$ok = @include_once(dirname(__FILE__).'/../vendor/vierbergenlars/simpletest/autorun.php');
|
||||||
|
}
|
||||||
|
if (!$ok) {
|
||||||
|
echo "MISSING DEPENDENCY: The Stripe API test cases depend on SimpleTest. ".
|
||||||
|
"Download it at <http://www.simpletest.org/>, and either install it ".
|
||||||
|
"in your PHP include_path or put it in the test/ directory.\n";
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Throw an exception on any error
|
||||||
|
function exception_error_handler($errno, $errstr, $errfile, $errline) {
|
||||||
|
throw new ErrorException($errstr, $errno, 0, $errfile, $errline);
|
||||||
|
}
|
||||||
|
set_error_handler('exception_error_handler');
|
||||||
|
error_reporting(E_ALL | E_STRICT);
|
||||||
|
|
||||||
|
require_once(dirname(__FILE__) . '/../lib/Stripe.php');
|
||||||
|
|
||||||
|
require_once(dirname(__FILE__) . '/Stripe/TestCase.php');
|
||||||
|
|
||||||
|
require_once(dirname(__FILE__) . '/Stripe/ApiRequestorTest.php');
|
||||||
|
require_once(dirname(__FILE__) . '/Stripe/AuthenticationErrorTest.php');
|
||||||
|
require_once(dirname(__FILE__) . '/Stripe/CardErrorTest.php');
|
||||||
|
require_once(dirname(__FILE__) . '/Stripe/AccountTest.php');
|
||||||
|
require_once(dirname(__FILE__) . '/Stripe/ChargeTest.php');
|
||||||
|
require_once(dirname(__FILE__) . '/Stripe/CouponTest.php');
|
||||||
|
require_once(dirname(__FILE__) . '/Stripe/CustomerTest.php');
|
||||||
|
require_once(dirname(__FILE__) . '/Stripe/DiscountTest.php');
|
||||||
|
require_once(dirname(__FILE__) . '/Stripe/Error.php');
|
||||||
|
require_once(dirname(__FILE__) . '/Stripe/InvalidRequestErrorTest.php');
|
||||||
|
require_once(dirname(__FILE__) . '/Stripe/InvoiceTest.php');
|
||||||
|
require_once(dirname(__FILE__) . '/Stripe/ObjectTest.php');
|
||||||
|
require_once(dirname(__FILE__) . '/Stripe/PlanTest.php');
|
||||||
|
require_once(dirname(__FILE__) . '/Stripe/Token.php');
|
||||||
|
require_once(dirname(__FILE__) . '/Stripe/TransferTest.php');
|
||||||
|
require_once(dirname(__FILE__) . '/Stripe/RecipientTest.php');
|
||||||
|
require_once(dirname(__FILE__) . '/Stripe/UtilTest.php');
|
||||||
13
vendor/stripe/stripe-php/test/Stripe/AccountTest.php
vendored
Normal file
13
vendor/stripe/stripe-php/test/Stripe/AccountTest.php
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class Stripe_AccountTest extends StripeTestCase
|
||||||
|
{
|
||||||
|
public function testRetrieve()
|
||||||
|
{
|
||||||
|
authorizeFromEnv();
|
||||||
|
$d = Stripe_Account::retrieve();
|
||||||
|
$this->assertEqual($d->email, "test+bindings@stripe.com");
|
||||||
|
$this->assertEqual($d->charge_enabled, false);
|
||||||
|
$this->assertEqual($d->details_submitted, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
64
vendor/stripe/stripe-php/test/Stripe/ApiRequestorTest.php
vendored
Normal file
64
vendor/stripe/stripe-php/test/Stripe/ApiRequestorTest.php
vendored
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class Stripe_ApiRequestorTest extends UnitTestCase
|
||||||
|
{
|
||||||
|
public function testEncode()
|
||||||
|
{
|
||||||
|
$a = array('my' => 'value', 'that' => array('your' => 'example'), 'bar' => 1, 'baz' => null);
|
||||||
|
$enc = Stripe_APIRequestor::encode($a);
|
||||||
|
$this->assertEqual($enc, 'my=value&that%5Byour%5D=example&bar=1');
|
||||||
|
|
||||||
|
$a = array('that' => array('your' => 'example', 'foo' => null));
|
||||||
|
$enc = Stripe_APIRequestor::encode($a);
|
||||||
|
$this->assertEqual($enc, 'that%5Byour%5D=example');
|
||||||
|
|
||||||
|
$a = array('that' => 'example', 'foo' => array('bar', 'baz'));
|
||||||
|
$enc = Stripe_APIRequestor::encode($a);
|
||||||
|
$this->assertEqual($enc, 'that=example&foo%5B%5D=bar&foo%5B%5D=baz');
|
||||||
|
|
||||||
|
$a = array('my' => 'value', 'that' => array('your' => array('cheese', 'whiz', null)), 'bar' => 1, 'baz' => null);
|
||||||
|
$enc = Stripe_APIRequestor::encode($a);
|
||||||
|
$this->assertEqual($enc, 'my=value&that%5Byour%5D%5B%5D=cheese&that%5Byour%5D%5B%5D=whiz&bar=1');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testUtf8()
|
||||||
|
{
|
||||||
|
// UTF-8 string
|
||||||
|
$x = "\xc3\xa9";
|
||||||
|
$this->assertEqual(Stripe_ApiRequestor::utf8($x), $x);
|
||||||
|
|
||||||
|
// Latin-1 string
|
||||||
|
$x = "\xe9";
|
||||||
|
$this->assertEqual(Stripe_ApiRequestor::utf8($x), "\xc3\xa9");
|
||||||
|
|
||||||
|
// Not a string
|
||||||
|
$x = TRUE;
|
||||||
|
$this->assertEqual(Stripe_ApiRequestor::utf8($x), $x);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testEncodeObjects()
|
||||||
|
{
|
||||||
|
// We have to do some work here because this is normally
|
||||||
|
// private. This is just for testing! Also it only works on PHP >=
|
||||||
|
// 5.3
|
||||||
|
if (version_compare(PHP_VERSION, '5.3.2', '>=')) {
|
||||||
|
$reflector = new ReflectionClass('Stripe_APIRequestor');
|
||||||
|
$method = $reflector->getMethod('_encodeObjects');
|
||||||
|
$method->setAccessible(true);
|
||||||
|
|
||||||
|
$a = array('customer' => new Stripe_Customer('abcd'));
|
||||||
|
$enc = $method->invoke(null, $a);
|
||||||
|
$this->assertEqual($enc, array('customer' => 'abcd'));
|
||||||
|
|
||||||
|
// Preserves UTF-8
|
||||||
|
$v = array('customer' => "☃");
|
||||||
|
$enc = $method->invoke(null, $v);
|
||||||
|
$this->assertEqual($enc, $v);
|
||||||
|
|
||||||
|
// Encodes latin-1 -> UTF-8
|
||||||
|
$v = array('customer' => "\xe9");
|
||||||
|
$enc = $method->invoke(null, $v);
|
||||||
|
$this->assertEqual($enc, array('customer' => "\xc3\xa9"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
14
vendor/stripe/stripe-php/test/Stripe/AuthenticationErrorTest.php
vendored
Normal file
14
vendor/stripe/stripe-php/test/Stripe/AuthenticationErrorTest.php
vendored
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class Stripe_AuthenticationErrorTest extends UnitTestCase
|
||||||
|
{
|
||||||
|
public function testInvalidCredentials()
|
||||||
|
{
|
||||||
|
Stripe::setApiKey('invalid');
|
||||||
|
try {
|
||||||
|
Stripe_Customer::create();
|
||||||
|
} catch (Stripe_AuthenticationError $e) {
|
||||||
|
$this->assertEqual(401, $e->getHttpStatus());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
16
vendor/stripe/stripe-php/test/Stripe/CardErrorTest.php
vendored
Normal file
16
vendor/stripe/stripe-php/test/Stripe/CardErrorTest.php
vendored
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class Stripe_CardErrorTest extends UnitTestCase
|
||||||
|
{
|
||||||
|
public function testDecline()
|
||||||
|
{
|
||||||
|
authorizeFromEnv();
|
||||||
|
try {
|
||||||
|
Stripe_Charge::create(array('amount' => 100, 'currency' => 'usd', 'card' => array('number' => '4000000000000002', 'exp_month' => '3', 'exp_year' => '2020')));
|
||||||
|
} catch (Stripe_CardError $e) {
|
||||||
|
$this->assertEqual(402, $e->getHttpStatus());
|
||||||
|
$body = $e->getJsonBody();
|
||||||
|
$this->assertTrue($body['error']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
35
vendor/stripe/stripe-php/test/Stripe/ChargeTest.php
vendored
Normal file
35
vendor/stripe/stripe-php/test/Stripe/ChargeTest.php
vendored
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class Stripe_ChargeTest extends UnitTestCase
|
||||||
|
{
|
||||||
|
public function testUrls()
|
||||||
|
{
|
||||||
|
$this->assertEqual(Stripe_Charge::classUrl('Stripe_Charge'), '/v1/charges');
|
||||||
|
$charge = new Stripe_Charge('abcd/efgh');
|
||||||
|
$this->assertEqual($charge->instanceUrl(), '/v1/charges/abcd%2Fefgh');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testCreate()
|
||||||
|
{
|
||||||
|
authorizeFromEnv();
|
||||||
|
$c = Stripe_Charge::create(array('amount' => 100,
|
||||||
|
'currency' => 'usd',
|
||||||
|
'card' => array('number' => '4242424242424242',
|
||||||
|
'exp_month' => 5,
|
||||||
|
'exp_year' => 2015)));
|
||||||
|
$this->assertTrue($c->paid);
|
||||||
|
$this->assertFalse($c->refunded);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testRetrieve()
|
||||||
|
{
|
||||||
|
authorizeFromEnv();
|
||||||
|
$c = Stripe_Charge::create(array('amount' => 100,
|
||||||
|
'currency' => 'usd',
|
||||||
|
'card' => array('number' => '4242424242424242',
|
||||||
|
'exp_month' => 5,
|
||||||
|
'exp_year' => 2015)));
|
||||||
|
$d = Stripe_Charge::retrieve($c->id);
|
||||||
|
$this->assertEqual($d->id, $c->id);
|
||||||
|
}
|
||||||
|
}
|
||||||
17
vendor/stripe/stripe-php/test/Stripe/CouponTest.php
vendored
Normal file
17
vendor/stripe/stripe-php/test/Stripe/CouponTest.php
vendored
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class Stripe_CouponTest extends StripeTestCase
|
||||||
|
{
|
||||||
|
public function testCreate()
|
||||||
|
{
|
||||||
|
authorizeFromEnv();
|
||||||
|
$id = 'test_coupon-' . self::randomString();
|
||||||
|
$c = Stripe_Coupon::create(array('percent_off' => 25,
|
||||||
|
'duration' => 'repeating',
|
||||||
|
'duration_in_months' => 5,
|
||||||
|
'id' => $id));
|
||||||
|
$this->assertEqual($id, $c->id);
|
||||||
|
$this->assertEqual(25, $c->percent_off);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
58
vendor/stripe/stripe-php/test/Stripe/CustomerTest.php
vendored
Normal file
58
vendor/stripe/stripe-php/test/Stripe/CustomerTest.php
vendored
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class Stripe_CustomerTest extends StripeTestCase
|
||||||
|
{
|
||||||
|
public function testDeletion()
|
||||||
|
{
|
||||||
|
$customer = self::createTestCustomer();
|
||||||
|
$customer->delete();
|
||||||
|
|
||||||
|
$this->assertTrue($customer->deleted);
|
||||||
|
$this->assertNull($customer['active_card']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testSave()
|
||||||
|
{
|
||||||
|
$customer = self::createTestCustomer();
|
||||||
|
|
||||||
|
$customer->email = 'gdb@stripe.com';
|
||||||
|
$customer->save();
|
||||||
|
$this->assertEqual($customer->email, 'gdb@stripe.com');
|
||||||
|
|
||||||
|
$customer2 = Stripe_Customer::retrieve($customer->id);
|
||||||
|
$this->assertEqual($customer->email, $customer2->email);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testBogusAttribute()
|
||||||
|
{
|
||||||
|
$customer = self::createTestCustomer();
|
||||||
|
$customer->bogus = 'bogus';
|
||||||
|
|
||||||
|
$caught = null;
|
||||||
|
try {
|
||||||
|
$customer->save();
|
||||||
|
} catch (Stripe_InvalidRequestError $exception) {
|
||||||
|
$caught = $exception;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->assertTrue($caught instanceof Stripe_InvalidRequestError);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testCancelSubscription()
|
||||||
|
{
|
||||||
|
$plan_id = 'gold-' . self::randomString();
|
||||||
|
self::retrieveOrCreatePlan($plan_id);
|
||||||
|
|
||||||
|
$customer = self::createTestCustomer(
|
||||||
|
array(
|
||||||
|
'plan' => $plan_id,
|
||||||
|
));
|
||||||
|
|
||||||
|
$customer->cancelSubscription(array('at_period_end' => true));
|
||||||
|
$this->assertEqual($customer->subscription->status, 'active');
|
||||||
|
$this->assertTrue($customer->subscription->cancel_at_period_end);
|
||||||
|
$customer->cancelSubscription();
|
||||||
|
$this->assertEqual($customer->subscription->status, 'canceled');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
25
vendor/stripe/stripe-php/test/Stripe/DiscountTest.php
vendored
Normal file
25
vendor/stripe/stripe-php/test/Stripe/DiscountTest.php
vendored
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class Stripe_DiscountTest extends StripeTestCase
|
||||||
|
{
|
||||||
|
public function testDeletion()
|
||||||
|
{
|
||||||
|
authorizeFromEnv();
|
||||||
|
$id = 'test-coupon-' . self::randomString();
|
||||||
|
$coupon = Stripe_Coupon::create(array('percent_off' => 25,
|
||||||
|
'duration' => 'repeating',
|
||||||
|
'duration_in_months' => 5,
|
||||||
|
'id' => $id));
|
||||||
|
$customer = self::createTestCustomer(array('coupon' => $id));
|
||||||
|
|
||||||
|
$this->assertTrue(isset($customer->discount));
|
||||||
|
$this->assertTrue(isset($customer->discount->coupon));
|
||||||
|
$this->assertEqual($id, $customer->discount->coupon->id);
|
||||||
|
|
||||||
|
$customer->deleteDiscount();
|
||||||
|
$this->assertFalse(isset($customer->discount));
|
||||||
|
|
||||||
|
$customer = Stripe_Customer::retrieve($customer->id);
|
||||||
|
$this->assertFalse(isset($customer->discount));
|
||||||
|
}
|
||||||
|
}
|
||||||
17
vendor/stripe/stripe-php/test/Stripe/Error.php
vendored
Normal file
17
vendor/stripe/stripe-php/test/Stripe/Error.php
vendored
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class Stripe_ErrorTest extends UnitTestCase
|
||||||
|
{
|
||||||
|
public function testCreation()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
throw new Stripe_Error("hello", 500, "{'foo':'bar'}", array('foo' => 'bar'));
|
||||||
|
$this->fail("Did not raise error");
|
||||||
|
} catch (Stripe_Error $e) {
|
||||||
|
$this->assertEqual("hello", $e->getMessage());
|
||||||
|
$this->assertEqual(500, $e->getHttpStatus());
|
||||||
|
$this->assertEqual("{'foo':'bar'}", $e->getHttpBody());
|
||||||
|
$this->assertEqual(array('foo' => 'bar'), $e->getJsonBody());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user