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';
|
include_once 'vendor/autoload.php';
|
||||||
|
|
||||||
use Illuminate\Database\Capsule\Manager as Capsule;
|
use Illuminate\Database\Capsule\Manager as Capsule;
|
||||||
use Krzysiej\RyobiCrawler\Models\Price;
|
|
||||||
use Krzysiej\RyobiCrawler\Models\Product;
|
use Krzysiej\RyobiCrawler\Models\Product;
|
||||||
|
use Twig\{Environment, Loader\FilesystemLoader};
|
||||||
|
|
||||||
$capsule = new Capsule;
|
$capsule = new Capsule;
|
||||||
$capsule->addConnection([
|
$capsule->addConnection(['driver' => 'sqlite', 'database' => __DIR__ . '/database.sqlite']);
|
||||||
'driver' => 'sqlite',
|
|
||||||
'database' => __DIR__ . '/database.sqlite',
|
|
||||||
'prefix' => '',
|
|
||||||
]);
|
|
||||||
$capsule->setAsGlobal();
|
$capsule->setAsGlobal();
|
||||||
$capsule->bootEloquent();
|
$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'])) {
|
if (isset($_GET['product_id'])) {
|
||||||
|
$template = 'product.html.twig';
|
||||||
$product = Product::with('price')->find($_GET['product_id']);
|
$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'])) {
|
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();
|
$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>
|
if (isset($_GET['search'])) {
|
||||||
<td>{$product->price->last()->price}</td>
|
$template = 'productList.html.twig';
|
||||||
</tr>";
|
$products = Product::with('price')
|
||||||
|
->orWhere([['name', 'like', "%{$_GET['search']}%"]])
|
||||||
|
->orWhere([['subTitle', 'like', "%{$_GET['search']}%"]])->get();
|
||||||
}
|
}
|
||||||
echo "</table>";
|
if (empty($_GET)) {
|
||||||
}
|
$template = 'productList.html.twig';
|
||||||
if (!isset($_GET['product_id']) && !isset($_GET['category'])) {
|
|
||||||
$products = Product::with('price')->get();
|
$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",
|
"guzzlehttp/guzzle": "^7.0",
|
||||||
"symfony/var-dumper": "^7.0",
|
"symfony/var-dumper": "^7.0",
|
||||||
"illuminate/database": "^11.0",
|
"illuminate/database": "^11.0",
|
||||||
"ext-json": "*"
|
"ext-json": "*",
|
||||||
|
"twig/twig": "^3.0"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"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",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "2de5a90e6e774457aaf4cab180a00f16",
|
"content-hash": "ce7d9a1457a9f208ddadf1630309fecc",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "brick/math",
|
"name": "brick/math",
|
||||||
@@ -1542,6 +1542,85 @@
|
|||||||
],
|
],
|
||||||
"time": "2023-05-23T14:45:45+00:00"
|
"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",
|
"name": "symfony/polyfill-mbstring",
|
||||||
"version": "v1.29.0",
|
"version": "v1.29.0",
|
||||||
@@ -2034,6 +2113,78 @@
|
|||||||
],
|
],
|
||||||
"time": "2024-02-15T11:33:06+00:00"
|
"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",
|
"name": "voku/portable-ascii",
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
@@ -2115,7 +2266,9 @@
|
|||||||
"stability-flags": [],
|
"stability-flags": [],
|
||||||
"prefer-stable": false,
|
"prefer-stable": false,
|
||||||
"prefer-lowest": false,
|
"prefer-lowest": false,
|
||||||
"platform": [],
|
"platform": {
|
||||||
|
"ext-json": "*"
|
||||||
|
},
|
||||||
"platform-dev": [],
|
"platform-dev": [],
|
||||||
"plugin-api-version": "2.3.0"
|
"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