135 lines
4.5 KiB
PHP
135 lines
4.5 KiB
PHP
<?php
|
|
|
|
namespace Sandpiper\Actions;
|
|
|
|
use \DOMDocument; use \DOMElement; use \DOMCDATASection;
|
|
|
|
use \Yosymfony\Toml\Toml;
|
|
|
|
use \SBRL\Utilities\SimpleXmlWriter;
|
|
|
|
class Report extends \Sandpiper\AbstractAction
|
|
{
|
|
|
|
public function __construct()
|
|
{
|
|
libxml_disable_entity_loader(false);
|
|
}
|
|
|
|
public function handle() {
|
|
global $settings;
|
|
|
|
header("content-type: text/plain");
|
|
|
|
if(!$this->param_exists("place_id"))
|
|
exit("Error: No place id provided.\n");
|
|
if(!$this->param_exists("summary"))
|
|
exit("Error: No summary provided.\n");
|
|
if(!$this->param_exists("version"))
|
|
exit("No version provided.\n");
|
|
|
|
/******************************************************/
|
|
|
|
$place = null;
|
|
foreach($settings->get("places") as $current_place) {
|
|
if($current_place["key"] == $this->param_get("place_id", null)) {
|
|
$place = $current_place;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if($place == null)
|
|
exit("Error: Place id doesn't match.\n");
|
|
|
|
$new_report = new \stdClass();
|
|
$new_report->version = escape4xml($this->param_get("version", "?"));
|
|
$new_report->summary = escape4xml($this->param_get("summary", "(Unknown error)"));
|
|
$new_report->details = escape4xml($this->param_get("details", ""));
|
|
$new_report->stack_trace = $this->get_post_body();
|
|
|
|
$report_dir = ROOT_DIR . "/{$settings->get("data_dir")}/places/" . slugify($place["name"]);
|
|
$report_filename = "$report_dir/" . slugify($new_report->summary) . ".xml";
|
|
|
|
// Create the directory if it doesn't exist already
|
|
if(!file_exists($report_dir))
|
|
mkdir($report_dir, 0750, true);
|
|
|
|
// Save the individual report
|
|
|
|
if(!file_exists($report_filename)) {
|
|
$writer = new \SBRL\Utilities\SimpleXmlWriter(); // It's started automagically
|
|
$writer->prettyprint = true;
|
|
$writer->add_xslt("/theme/stack_traces.xslt");
|
|
$writer->open("error_info");
|
|
$writer->addtag("project_name", [], $place["name"]); // For aesthetic purposes
|
|
$writer->addtag("summary", [], $new_report->summary);
|
|
$writer->open("reports");
|
|
$writer->close();
|
|
$writer->close();
|
|
file_put_contents($report_filename, $writer->render());
|
|
}
|
|
|
|
// We have to use a DOMDocument here because SimpleXML mangled the
|
|
// whitespace in the stack traces
|
|
$report_xml = new DOMDocument("1.0", "UTF-8");
|
|
$report_xml->preserveWhiteSpace = false;
|
|
$report_xml->formatOutput = true;
|
|
if(!$report_xml->loadXML(file_get_contents($report_filename), LIBXML_NONET))
|
|
exit("Error: Invalid XML generated when creating a new report file.\n");
|
|
|
|
$report_node = new DOMElement("report");
|
|
$report_xml->getElementsByTagName("reports")->item(0)->appendChild($report_node);
|
|
|
|
$report_node->appendChild(new DOMElement("timestamp", date(DATE_ATOM)));
|
|
$report_node->appendChild(new DOMElement("version", $new_report->version));
|
|
$report_node->appendChild(new DOMElement("details", $new_report->details));
|
|
$stack_trace_node = new DOMElement("stack_trace");
|
|
$report_node->appendChild($stack_trace_node);
|
|
$stack_trace_node->appendChild($report_xml->createCDATASection($new_report->stack_trace));
|
|
|
|
// NOTE: When uploading with curl to test this, make sure to use --data-binary and not simply -d, as this mangles the newline characters.
|
|
file_put_contents($report_filename, $report_xml->saveXML());
|
|
|
|
// Update the place index
|
|
$place_index_filename = "$report_dir/index.xml";
|
|
|
|
if(!file_exists($place_index_filename)) {
|
|
$writer = new SimpleXmlWriter();
|
|
$writer->prettyprint = true;
|
|
|
|
$writer->add_xslt("/theme/error_index.xslt");
|
|
$writer->open("errors_index");
|
|
$writer->addtag("project_name", [], $place["name"]);
|
|
$writer->open("error_list");
|
|
$writer->close();
|
|
$writer->close();
|
|
file_put_contents($place_index_filename, $writer->render());
|
|
}
|
|
$index_xml = simplexml_load_file($place_index_filename);
|
|
|
|
$index_entry = null;
|
|
foreach($index_xml->error_list as $entry) {
|
|
if($entry->summary->__toString() != $new_report->summary)
|
|
continue;
|
|
$index_entry = $entry;
|
|
break;
|
|
}
|
|
|
|
if($index_entry == null) {
|
|
$index_entry = $index_xml->error_list->addChild("error");
|
|
$index_entry->summary = $new_report->summary;
|
|
$index_entry->last_report = date(DATE_ATOM);
|
|
$index_entry->filename = basename($report_filename);
|
|
$index_entry->report_count = 0;
|
|
}
|
|
|
|
$index_entry->report_count = intval($index_entry->report_count) + 1;
|
|
|
|
// This is fine because we don't have to worry about the whitespace in the
|
|
// stack traces here
|
|
file_put_contents($place_index_filename, simplexml_asxml_pretty($index_xml));
|
|
|
|
http_response_code(200);
|
|
exit("Report submitted successfully!\n");
|
|
}
|
|
}
|