Added twig template, templates and search functionality.
This commit is contained in:
76
browser.php
76
browser.php
@@ -3,78 +3,32 @@
|
||||
include_once 'vendor/autoload.php';
|
||||
|
||||
use Illuminate\Database\Capsule\Manager as Capsule;
|
||||
use Krzysiej\RyobiCrawler\Models\Price;
|
||||
use Krzysiej\RyobiCrawler\Models\Product;
|
||||
use Twig\{Environment, Loader\FilesystemLoader};
|
||||
|
||||
$capsule = new Capsule;
|
||||
$capsule->addConnection([
|
||||
'driver' => 'sqlite',
|
||||
'database' => __DIR__ . '/database.sqlite',
|
||||
'prefix' => '',
|
||||
]);
|
||||
$capsule->addConnection(['driver' => 'sqlite', 'database' => __DIR__ . '/database.sqlite']);
|
||||
$capsule->setAsGlobal();
|
||||
$capsule->bootEloquent();
|
||||
echo '<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous"></head>';
|
||||
$loader = new FilesystemLoader(__DIR__ . '/src/templates');
|
||||
$twig = new Environment($loader);
|
||||
if (isset($_GET['product_id'])) {
|
||||
$template = 'product.html.twig';
|
||||
$product = Product::with('price')->find($_GET['product_id']);
|
||||
echo "<a href='/browser.php'>back</a><table class='table table-hover'>";
|
||||
echo "<tr>
|
||||
<td><img src='$product->image&width=150' class='img-fluid' alt='$product->name'/></td>
|
||||
<td><a href='?product_id=$product->id'>$product->name</a></td>
|
||||
<td>$product->subTitle</td>
|
||||
<td><a href='https://pl.ryobitools.eu/{$product->url}'>link</a></td></tr>";
|
||||
echo "</table>";
|
||||
echo "<table class='table table-hover'>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>price</th>
|
||||
<th>lowest product price in 30 days</th>
|
||||
<th colspan='2'>standard price</th>
|
||||
</tr>
|
||||
</thead>";
|
||||
/** @var Price $price */
|
||||
foreach ($product->price as $price) {
|
||||
echo "<tr>
|
||||
<td>$price->price</td>
|
||||
<td>$price->lowestProductPrice30Days</td>
|
||||
<td>$price->productStandardPrice</td>
|
||||
<td>$price->created_at</td>
|
||||
</tr>";
|
||||
}
|
||||
echo "</table>";
|
||||
}
|
||||
if (isset($_GET['category'])) {
|
||||
echo "<a href='/browser.php'>back</a><table class='table table-hover'>";
|
||||
$template = 'productList.html.twig';
|
||||
$products = Product::with('price')->selectRaw('products.*')->fromRaw('products, json_each(products.categories)')->whereRaw('json_each.value = ?', [$_GET['category']])->get();
|
||||
echo "<table class='table table-hover'>";
|
||||
foreach ($products as $product) {
|
||||
echo "<tr>
|
||||
<td><img src='$product->image&width=70' class='img-fluid' alt='$product->name' /></td>
|
||||
<td><a href='?product_id=$product->id'>$product->name</a></td>
|
||||
<td>$product->subTitle</td><td><ul class='nav'>";
|
||||
foreach ($product->categories as $category) {
|
||||
echo '<li class="nav-item"><a class="nav-link" href="?category=' . $category . '">' . $category . '</a></li>';
|
||||
}
|
||||
echo "</td><td><a href='https://pl.ryobitools.eu/{$product->url}'>link</a></td>
|
||||
<td>{$product->price->last()->price}</td>
|
||||
</tr>";
|
||||
if (isset($_GET['search'])) {
|
||||
$template = 'productList.html.twig';
|
||||
$products = Product::with('price')
|
||||
->orWhere([['name', 'like', "%{$_GET['search']}%"]])
|
||||
->orWhere([['subTitle', 'like', "%{$_GET['search']}%"]])->get();
|
||||
}
|
||||
echo "</table>";
|
||||
}
|
||||
if (!isset($_GET['product_id']) && !isset($_GET['category'])) {
|
||||
if (empty($_GET)) {
|
||||
$template = 'productList.html.twig';
|
||||
$products = Product::with('price')->get();
|
||||
echo "<table class='table table-hover'>";
|
||||
foreach ($products as $product) {
|
||||
echo "<tr>
|
||||
<td><img src='$product->image&width=70' class='img-fluid' alt='$product->name' /></td>
|
||||
<td><a href='?product_id=$product->id'>$product->name</a></td>
|
||||
<td>$product->subTitle</td><td><ul class='nav'>";
|
||||
foreach ($product->categories as $category) {
|
||||
echo '<li class="nav-item"><a class="nav-link" href="?category=' . $category . '">' . $category . '</a></li>';
|
||||
}
|
||||
echo "</td><td><a href='https://pl.ryobitools.eu/{$product->url}'>link</a></td>
|
||||
<td>{$product->price->last()->price}</td>
|
||||
</tr>";
|
||||
}
|
||||
echo "</table>";
|
||||
}
|
||||
|
||||
$twig->display($template, ['products' => $products, 'product' => $product, 'search' => $_GET['search']]);
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
"guzzlehttp/guzzle": "^7.0",
|
||||
"symfony/var-dumper": "^7.0",
|
||||
"illuminate/database": "^11.0",
|
||||
"ext-json": "*"
|
||||
"ext-json": "*",
|
||||
"twig/twig": "^3.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
|
||||
157
composer.lock
generated
157
composer.lock
generated
@@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "2de5a90e6e774457aaf4cab180a00f16",
|
||||
"content-hash": "ce7d9a1457a9f208ddadf1630309fecc",
|
||||
"packages": [
|
||||
{
|
||||
"name": "brick/math",
|
||||
@@ -1542,6 +1542,85 @@
|
||||
],
|
||||
"time": "2023-05-23T14:45:45+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-ctype",
|
||||
"version": "v1.29.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-ctype.git",
|
||||
"reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ef4d7e442ca910c4764bce785146269b30cb5fc4",
|
||||
"reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1"
|
||||
},
|
||||
"provide": {
|
||||
"ext-ctype": "*"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-ctype": "For best performance"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
"url": "https://github.com/symfony/polyfill"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Symfony\\Polyfill\\Ctype\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Gert de Pagter",
|
||||
"email": "BackEndTea@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony polyfill for ctype functions",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"compatibility",
|
||||
"ctype",
|
||||
"polyfill",
|
||||
"portable"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.29.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-01-29T20:11:03+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-mbstring",
|
||||
"version": "v1.29.0",
|
||||
@@ -2034,6 +2113,78 @@
|
||||
],
|
||||
"time": "2024-02-15T11:33:06+00:00"
|
||||
},
|
||||
{
|
||||
"name": "twig/twig",
|
||||
"version": "v3.8.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/twigphp/Twig.git",
|
||||
"reference": "9d15f0ac07f44dc4217883ec6ae02fd555c6f71d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/twigphp/Twig/zipball/9d15f0ac07f44dc4217883ec6ae02fd555c6f71d",
|
||||
"reference": "9d15f0ac07f44dc4217883ec6ae02fd555c6f71d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2.5",
|
||||
"symfony/polyfill-ctype": "^1.8",
|
||||
"symfony/polyfill-mbstring": "^1.3",
|
||||
"symfony/polyfill-php80": "^1.22"
|
||||
},
|
||||
"require-dev": {
|
||||
"psr/container": "^1.0|^2.0",
|
||||
"symfony/phpunit-bridge": "^5.4.9|^6.3|^7.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Twig\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com",
|
||||
"homepage": "http://fabien.potencier.org",
|
||||
"role": "Lead Developer"
|
||||
},
|
||||
{
|
||||
"name": "Twig Team",
|
||||
"role": "Contributors"
|
||||
},
|
||||
{
|
||||
"name": "Armin Ronacher",
|
||||
"email": "armin.ronacher@active-4.com",
|
||||
"role": "Project Founder"
|
||||
}
|
||||
],
|
||||
"description": "Twig, the flexible, fast, and secure template language for PHP",
|
||||
"homepage": "https://twig.symfony.com",
|
||||
"keywords": [
|
||||
"templating"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/twigphp/Twig/issues",
|
||||
"source": "https://github.com/twigphp/Twig/tree/v3.8.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/twig/twig",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-11-21T18:54:41+00:00"
|
||||
},
|
||||
{
|
||||
"name": "voku/portable-ascii",
|
||||
"version": "2.0.1",
|
||||
@@ -2115,7 +2266,9 @@
|
||||
"stability-flags": [],
|
||||
"prefer-stable": false,
|
||||
"prefer-lowest": false,
|
||||
"platform": [],
|
||||
"platform": {
|
||||
"ext-json": "*"
|
||||
},
|
||||
"platform-dev": [],
|
||||
"plugin-api-version": "2.3.0"
|
||||
}
|
||||
|
||||
42
src/templates/product.html.twig
Normal file
42
src/templates/product.html.twig
Normal file
@@ -0,0 +1,42 @@
|
||||
{% extends "template.html.twig" %}
|
||||
|
||||
{% block content %}
|
||||
<table class='table table-hover'>
|
||||
<tr>
|
||||
<td><img src='{{ product.image }}&width=150' class='img-fluid' alt='{{ product.name }}'/></td>
|
||||
<td><a href='?product_id={{ product.id }}'>{{ product.name }}</a></td>
|
||||
<td>{{ product.subTitle }}</td>
|
||||
<td>
|
||||
<ul class='nav'>
|
||||
{% for category in product.categories %}
|
||||
<li class="nav-item"><a class="nav-link" href="?category={{ category }}"> {{ category }} </a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</td>
|
||||
<td><a href='https://pl.ryobitools.eu/{{ product.url }}'>link</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="4">
|
||||
|
||||
<table class='table table-hover table-sm mb-0'>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>price</th>
|
||||
<th>lowest product price in 30 days</th>
|
||||
<th colspan='2'>standard price</th>
|
||||
</tr>
|
||||
</thead>
|
||||
{% for price in product.price %}
|
||||
<tr>
|
||||
<td>{{ price.price }}</td>
|
||||
<td>{{ price.lowestProductPrice30Days }}</td>
|
||||
<td>{{ price.productStandardPrice }}</td>
|
||||
<td>{{ price.created_at }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
{% endblock %}
|
||||
|
||||
22
src/templates/productList.html.twig
Normal file
22
src/templates/productList.html.twig
Normal file
@@ -0,0 +1,22 @@
|
||||
{% extends "template.html.twig" %}
|
||||
|
||||
{% block content %}
|
||||
<table class='table table-hover'>
|
||||
{% for product in products %}
|
||||
<tr>
|
||||
<td><img src='{{ product.image }}&width=70' class='img-fluid' alt='{{ product.name }}'/></td>
|
||||
<td><a href='?product_id={{ product.id }}'>{{ product.name }}</a></td>
|
||||
<td>{{ product.subTitle }}</td>
|
||||
<td>
|
||||
<ul class='nav'>
|
||||
{% for category in product.categories %}
|
||||
<li class="nav-item"><a class="nav-link" href="?category={{ category }}"> {{ category }} </a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</td>
|
||||
<td><a href='https://pl.ryobitools.eu/{{ product.url }}'>link</a></td>
|
||||
<td>{{ product.price.last.price }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% endblock %}
|
||||
24
src/templates/template.html.twig
Normal file
24
src/templates/template.html.twig
Normal file
@@ -0,0 +1,24 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<title>Ryobi crawler</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH"
|
||||
crossorigin="anonymous"/>
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar sticky-top bg-body-tertiary">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" href="/browser.php">Crawler</a>
|
||||
<form class="d-flex" role="search">
|
||||
<input class="form-control me-2" type="search" name="search" placeholder="Search" value="{{ search }}" aria-label="Search">
|
||||
<button class="btn btn-outline-success" type="submit">Search</button>
|
||||
</form>
|
||||
</div>
|
||||
</nav>
|
||||
{% block content %}{% endblock %}
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user