feat: Add XML file management functionality

- Created XmlFiles control class for handling XML file views and regeneration.
- Implemented method to retrieve clients with XML feeds in the factory class.
- Added database migration to include google_merchant_account_id in clients table.
- Created migrations for products_keyword_planner_terms and products_merchant_sync_log tables.
- Added campaign_keywords table migration for managing campaign keyword data.
- Developed main view template for displaying XML files and their statuses.
- Introduced a debug script for analyzing product URLs and their statuses.
This commit is contained in:
2026-02-18 21:23:53 +01:00
parent 3dc06d505a
commit efbdcce08a
36 changed files with 8778 additions and 2615 deletions

View File

@@ -1,56 +1,60 @@
<div class="admin-form theme-primary">
<div class="panel heading-border panel-primary">
<div class="panel-body">
<div class="chart-with-form">
<div class="chart-area">
<figure class="highcharts-figure">
<div id="container"></div>
</figure>
</div>
<div class="products-page product-history-page">
<div class="products-header">
<h2><i class="fa-solid fa-chart-line"></i> Historia produktu #<?= (int) $this -> product_id; ?></h2>
<a href="/products" class="btn btn-primary btn-sm">
<i class="fa-solid fa-arrow-left"></i> Powrot do produktow
</a>
</div>
<!-- PRAWY PANEL: formularz komentarza -->
<aside class="comment-form admin-form theme-primary">
<form id="product-comment-form" autocomplete="off">
<div class="form-group">
<label for="comment_date">Data</label>
<input type="date" id="comment_date" name="date" required>
</div>
<div class="form-group">
<label for="comment_text">Komentarz</label>
<textarea id="comment_text" name="comment" placeholder="Wpisz komentarz..." required></textarea>
</div>
<button type="submit" class="btn" id="save_comment">Zapisz komentarz</button>
</form>
</aside>
<div class="product-history-meta">
<span>Klient: #<?= (int) $this -> client_id; ?></span>
<span>Kampania: <?= (int) ( $this -> campaign_id ?? 0 ); ?></span>
<span>Grupa reklam: <?= (int) ( $this -> ad_group_id ?? 0 ); ?></span>
</div>
<div class="product-history-chart-wrap">
<div class="chart-with-form">
<div class="chart-area">
<div class="product-history-chart" id="container"></div>
</div>
<aside class="comment-form">
<form id="product-comment-form" autocomplete="off">
<div class="form-group">
<label for="comment_date">Data</label>
<input type="date" id="comment_date" name="date" required>
</div>
<div class="form-group">
<label for="comment_text">Komentarz</label>
<textarea id="comment_text" name="comment" placeholder="Wpisz komentarz..." required></textarea>
</div>
<button type="submit" class="btn btn-primary btn-sm" id="save_comment">
<i class="fa-solid fa-floppy-disk"></i> Zapisz komentarz
</button>
</form>
</aside>
</div>
</div>
</div>
<div class="admin-form theme-primary">
<div class="panel heading-border panel-primary">
<div class="panel-body">
<table class="table" id="products">
<thead>
<tr>
<th scope="col">Id</th>
<th scope="col">Wyświetlenia</th>
<th scope="col">Kliknięcia</th>
<th scope="col">CTR</th>
<th scope="col">Koszt</th>
<th scope="col">Konwersje</th>
<th scope="col">Wartość konwersji</th>
<th scope="col">ROAS</th>
<th scope="col">Data</th>
<th scope="col">Komentarz</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
<div class="products-table-wrap">
<table class="table table-sm" id="products">
<thead>
<tr>
<th scope="col">Id</th>
<th scope="col">Wyswietlenia</th>
<th scope="col">Klikniecia</th>
<th scope="col">CTR</th>
<th scope="col">Koszt</th>
<th scope="col">Konwersje</th>
<th scope="col">Wartosc konwersji</th>
<th scope="col">ROAS</th>
<th scope="col">Data</th>
<th scope="col">Komentarz</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
</div>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script type="text/javascript">
@@ -71,14 +75,13 @@
})();
// Inicjalizacja tabeli
var table = $('#products').DataTable();
table.destroy();
new DataTable('#products', {
var table = new DataTable('#products', {
ajax: {
type: 'POST',
url: '/products/get_product_history_table/client_id=' + client_id + '&product_id=' + product_id + '&campaign_id=' + campaign_id + '&ad_group_id=' + ad_group_id,
},
autoWidth: false,
lengthChange: false,
pageLength: 30,
processing: true,
serverSide: true,
@@ -95,7 +98,19 @@
{ width: '100px', name: 'date_add' },
{ width: '250px', name: 'comment', orderable: false },
],
order: [[0, false],[8, 'desc']]
order: [ [ 8, 'desc' ] ],
language: {
processing: 'Ladowanie...',
emptyTable: 'Brak danych do wyswietlenia',
info: 'Wiersze _START_ - _END_ z _TOTAL_',
infoEmpty: '',
paginate: {
first: 'Pierwsza',
last: 'Ostatnia',
next: 'Dalej',
previous: 'Wstecz'
}
}
});
// WYKRES