Все переписано на фасады

This commit is contained in:
2024-09-03 15:41:45 +03:00
parent 74ba48620c
commit 48b4d6cccf
34 changed files with 1036 additions and 807 deletions

View File

@ -0,0 +1,71 @@
<?php
namespace ContingentParser\Parser;
class ContingentFacade
{
/**
* Получить данные о численности
* @param string $html
* Разметка сайта вуза
* @param mixed $specialties
* Массив специальностей
* @param int $orgId
* Идентификатор организации
* @return array
*/
public function getContingent(
string $html,
array $specialties,
int $orgId
) : array {
$parser = new ContingentParser($html);
$contingent = $parser->getDataTable();
$this->addSpecId($contingent, $specialties);
$this->addOrgId($contingent, $orgId);
return $contingent;
}
/**
* Проверка на валидность записи численнести
* @param array $contingent
* Массив численности по специальностям
* @return bool
*/
public function isValidContingent(array $contingent) : bool
{
$count = 0;
foreach ($contingent as $value) {
$count += $value['contingent'];
}
return $count ? true : false;
}
/**
* Добавить идентификатор специальности в запись численности
* @param array $contingent
* Массив численности по специальностям
* @param array $specialties
* Массив специальностей
* @return void
*/
private function addSpecId(array &$contingent, array $specialties) : void
{
$specIdMap = array_column($specialties, 'spec_id', 'spec_code');
foreach ($contingent as $key => $con) {
$contingent[$key]['spec_id'] = $specIdMap[$con['spec_code']] ?? null;
}
}
/**
* Добавить идентификатор организации в запись численности
* @param array $contingent
* Массив численности по специальностям
* @param int $orgId
* Идентифиактор организации
* @return void
*/
private function addOrgId(array &$contingent, int $orgId): void
{
foreach ($contingent as &$con) {
$con['org_id'] = $orgId;
}
}
}

View File

@ -0,0 +1,99 @@
<?php
namespace ContingentParser\Parser;
use DOMDocument;
use DOMXPath;
class ContingentParser
{
private ?DOMXPath $xpath;
private const TEMPLATE = '//tr[@itemprop="eduChislen"]//';
private const ENCODING = "UTF-8";
private const FIELDS = [
"eduCode" => "td",
"eduName" => "td",
"eduLevel" => "td",
"eduForm" => "td",
"numberAll" => ["th", "td"]
];
public function __construct(string $html)
{
libxml_use_internal_errors(true);
$dom = new DOMDocument(
encoding: self::ENCODING
);
if (empty($html)) {
$this->xpath = null;
} else {
$this->setEncoding($html);
$dom->loadHTML($html);
$this->xpath = new DOMXPath($dom);
}
}
private function setEncoding(string &$html) : void
{
$encoding = mb_detect_encoding($html, 'UTF-8, windows-1251');
if ($encoding != self::ENCODING) {
$html = mb_convert_encoding(
$html,
self::ENCODING,
$encoding
);
$html = str_replace('windows-1251',self::ENCODING, $html);
}
$html = mb_convert_encoding($html,'HTML-ENTITIES','UTF-8');
}
private function parse() : array
{
$data = [];
foreach (self::FIELDS as $field => $tag) {
if (!is_array($tag)) {
$data[$field] = $this->xpath->query(
self::TEMPLATE . $tag . "[@itemprop=\"$field\"]"
);
} else {
$th = $this->xpath->query(
self::TEMPLATE . $tag[0] . "[@itemprop=\"$field\"]"
);
$td = $this->xpath->query(
self::TEMPLATE . $tag[1] . "[@itemprop=\"$field\"]"
);
$data[$field] = $th->length > $td->length ? $th : $td;
}
}
return $data;
}
public function getDataTable() : array
{
if (empty($this->xpath)) return [];
$data = $this->parse();
$records = [];
if ($data == null) return [];
$equal = $data['eduName']->length;
foreach ($data as $field) {
if ($field->length == 0) {
return [];
}
if ($field->length != $equal) {
return [];
}
}
for ($i = 0; $i < $data['eduCode']->length; $i++) {
$contingentRow = new ContingentRow(
$data['eduCode']->item($i)->textContent,
$data['eduName']->item($i)->textContent,
$data['eduLevel']->item($i)->textContent,
$data['eduForm']->item($i)->textContent,
(int)$data['numberAll']->item($i)->textContent
);
$records[] = $contingentRow->getData();
}
return $records;
}
}

View File

@ -0,0 +1,33 @@
<?php
namespace ContingentParser\Parser;
class ContingentRow
{
public function __construct(
private string $eduCode,
private string $eduName,
private string $eduLevel,
private string $eduForm,
private int $contingent
) {
if ($contingent < 0) {
throw new \Exception("Недействительная численность обучающихся!");
}
$this->eduCode = trim($eduCode);
$this->eduName = trim($eduName);
$this->eduLevel = trim($eduLevel);
$this->eduForm = trim($eduForm);
$this->contingent = $contingent;
}
public function getData() : array
{
return [
"spec_code" => $this->eduCode,
"spec_name" => $this->eduName,
"edu_level" => $this->eduLevel,
"edu_forms"=> $this->eduForm,
"contingent" => $this->contingent
];
}
}