Added twig template, templates and search functionality.

This commit is contained in:
Krzysztof Płaczek
2024-03-28 16:07:19 +01:00
parent 5d0a44946f
commit d2abfba355
6 changed files with 261 additions and 65 deletions

View File

@@ -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>";
}
echo "</table>";
}
if (!isset($_GET['product_id']) && !isset($_GET['category'])) {
if (isset($_GET['search'])) {
$template = 'productList.html.twig';
$products = Product::with('price')
->orWhere([['name', 'like', "%{$_GET['search']}%"]])
->orWhere([['subTitle', 'like', "%{$_GET['search']}%"]])->get();
}
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']]);

View File

@@ -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
View File

@@ -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"
}

View 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 %}

View 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 %}

View 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>