A whole lotta stuff.

This commit is contained in:
Dan Chadwick
2024-03-13 15:48:45 +00:00
parent 5ff8b4b357
commit d7f37baeb7
372 changed files with 12650 additions and 378 deletions

View File

@@ -0,0 +1,313 @@
<?php
namespace Drupal\ufc;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\ufc\Fighter;
use Drupal\node\Entity\Node;
use Drupal\Core\Entity\EntityTypeManager;
use Drupal\Core\Config\ConfigFactory;
class FightPredictor {
/**
* First Fighter.
*
* @var Drupal\node\Entity\Node
*/
protected $fighterOne;
/**
* Second Fighter.
*
* @var Drupal\node\Entity\Node
*/
protected $fighterTwo;
/**
* Entity Type Manager.
*
* @var Drupal\Core\Entity\EntityTypeManager
*/
protected $entityTypeManager;
/**
* Config for ufc weights.
*
* @var Drupal\Core\Config\ConfigFactory
*/
protected $config;
/**
* Weights config object.
*
* @var Drupal\Core\Config\ConfigFactory
*/
protected $weights;
/**
* Public constructor.
*/
public function __construct(EntityTypeManager $entityTypeManager, ConfigFactory $config) {
$this->entityTypeManager = $entityTypeManager;
$this->config = $config->getEditable('ufc.weights');
$this->weights = $config->getEditable('ufc.weights')->get('fight_weights');
}
/**
* The results of the fight.
*
* @var array
*/
protected $results = [
'fighter_one' => [
'name' => null,
'points' => 0,
'advantages' => [],
'disadvantages' => []
],
'fighter_two' => [
'name' => null,
'points' => 0,
'advantages' => [],
'disadvantages' => []
],
'skips' => 0
];
/**
* The amount of categories skipped.
*
* @var int
*/
protected $skipCount;
/**
* Calculate the fight results.
*/
public function calculate(Node $fighter_one, Node $fighter_two) {
// Reset skip count.
$this->skipCount = 0;
// First Fighter.
$this->fighterOne = $fighter_one;
// Second Fighter.
$this->fighterTwo = $fighter_two;
// Run the fight.
$this->runFight();
// Label the results array.
$this->results['fighter_one']['name'] = $fighter_one->label();
$this->results['fighter_two']['name'] = $fighter_two->label();
// Add total skips.
$this->results['skips'] = $this->skipCount;
// echo "<pre>";
// print_r($this->results);
// echo "</pre>";
// exit();
return $this->results;
}
/**
* Populate fight results.
*
* @return void
*/
public function runFight() {
$points = 0;
$this->calcComparativePoints();
}
/**
* Calculate comparative points.
*
* @return void
*/
public function calcComparativePoints() {
$this->calculateDiff('field_height', 'height');
$this->calculateDiff('field_weight', 'weight');
$this->calculateDiff('field_age', 'age');
$this->calculateDiff('field_reach', 'reach');
$this->calculateDiff('field_leg_reach', 'leg_reach');
$this->calculateDiff('field_wins', 'wins');
$this->calculateDiff('field_losses', 'losses', TRUE);
$this->calculateDiff('field_ties', 'ties');
$this->calculateDiff('field_decisions', 'decisions');
$this->calculateDiff('field_knockouts', 'knockouts');
$this->calculateDiff('field_submissions', 'submissions');
$this->calculateDiff('field_grappling_accuracy', 'grappling_accuracy');
$this->calculateDiff('field_striking_accuracy', 'striking_accuracy');
$this->calculateDiff('field_strikes_per_minute', 'strikes_per_minute');
$this->calculateDiff('field_absorbed_per_min', 'absorbed_per_min', TRUE);
$this->calculateDiff('field_takedowns_per_15', 'takedowns_per_15');
$this->calculateDiff('field_knockdown_ratio', 'knockdown_ratio');
}
/**
* Calculate the weighted diff between two fighters.
*
* @param [type] $field
* @param [type] $weight_label
* @return void
*/
public function calculateDiff($field, $weight_label, $inverse = FALSE) {
$f1 = $this->getFieldValue($field, $this->fighterOne);
$f2 = $this->getFieldValue($field, $this->fighterTwo);
if (empty($f1) || empty($f2)) {
$this->skipCount += 1;
return;
}
$weighted_points = 1 * $this->config->get('fight_weights')[$weight_label];
if ($f1 === $f2) {
$this->skipCount += 1;
return;
}
if ($inverse) {
if ($f1 < $f2) {
$this->results['fighter_one']['points'] += $weighted_points;
$this->results['fighter_one']['advantages'][] = $field;
$this->results['fighter_two']['disadvantages'][] = $field;
return;
}
elseif ($f1 > $f2) {
$this->results['fighter_two']['points'] += $$weighted_points;
$this->results['fighter_two']['advantages'][] = $field;
$this->results['fighter_one']['disadvantages'][] = $field;
return;
}
}
else {
if ($f1 > $f2) {
$this->results['fighter_one']['points'] += $weighted_points;
$this->results['fighter_one']['advantages'][] = $field;
$this->results['fighter_two']['disadvantages'][] = $field;
}
elseif ($f1 < $f2) {
$this->results['fighter_two']['points'] += $weighted_points;
$this->results['fighter_two']['advantages'][] = $field;
$this->results['fighter_one']['disadvantages'][] = $field;
}
}
}
/**
* Get value from a field.
*/
public function getFieldValue($field, Node $fighter) {
$field_values = reset($fighter->get($field)->getValue());
if (empty($field_values['value'])) {
return 0;
}
return (float) $field_values['value'];
}
/**
* Calculate the knockout percentage for a fighter.
*
* @param Node $fighter
* @return void
*/
public function getKnockoutPercentage(Node $fighter) {
$total_fights =
$this->getFieldValue('field_wins', $fighter) +
$this->getFieldValue('field_losses', $fighter) +
$this->getFieldValue('field_ties', $fighter);
$knockout_pct = $this->getFieldValue('field_knockouts', $fighter) / $total_fights;
return $knockout_pct;
}
/**
* Update predictions for all fights in batches
*/
public function updatePredictionsBatched($fights, &$context) {
// $fights = $this->entityTypeManager->getStorage('node')->loadByProperties(['type' => 'fight']);
$results = [];
foreach ($fights as $fight) {
\Drupal::logger('ufc')->notice("Starting " . $fight->label() . "");
$fight->save();
$results[] = $fight->id();
}
$context['results'] = $results;
}
/**
* Update predictions for all fights.
*/
public function updatePredictions() {
$fights = $this->entityTypeManager->getStorage('node')->loadByProperties(['type' => 'fight']);
// $count = 0;
foreach ($fights as $fight) {
\Drupal::logger('ufc')->notice("Starting " . $fight->label() . "");
$fight->save();
// if ($count == 4) {
// return;
// }
// $count++;
}
}
public function adjustWeights($adv, $dis_adv) {
foreach ($adv as $cat_to_increase) {
$clean = str_replace('field_', '', $cat_to_increase);
$this->adjustWeight($clean, 2);
}
foreach ($dis_adv as $cat_to_decrease) {
$clean = str_replace('field_', '', $cat_to_decrease);
$this->adjustWeight($clean, -1);
}
}
/**
* Helper function to increase the weight of a category.
*/
public function adjustWeight($key, $increment) {
$current_val = $this->config->get('fight_weights')[$key];
$increase = $current_val + $increment;
$target = 'fight_weights.' . $key;
$this->config->set($target, $increase)->save();
}
/**
* Helper function to reset all weighting.
*
* @return void
*/
public function resetWeights() {
foreach ($this->config->get('fight_weights') as $cat => $weight) {
$this->config->set('fight_weights.' . $cat, 1)->save();
}
}
public function fightUpdatedCallback($success, $results, $operations) {
// The 'success' parameter means no fatal PHP errors were detected. All
// other error management should be handled using 'results'.
if ($success) {
$message = \Drupal::translation()->formatPlural(
count($results),
'One fight processed.', '@count fight processed.'
);
}
else {
$message = t('Finished with an error.');
}
drupal_set_message($message);
}
}

View File

@@ -0,0 +1,511 @@
<?php
namespace Drupal\ufc;
use Drupal\media\Entity\Media;
use Drupal\node\Entity\Node;
use Drupal\Component\Utility\Html;
use GuzzleHttp\Client;
use Drupal\taxonomy\Entity\Term;
class Fighter {
public $name;
public $first_name;
public $last_name;
public $height;
public $weight;
public $age;
public $reach;
public $leg_reach;
public $image;
public $image_id;
public $class;
public $wins;
public $losses;
public $ties;
public $http_client;
public $fighter_page;
public $striking_accuracy;
public $grappling_accuracy;
public $strikes_per_min;
public $absorbed_per_min;
public $takedowns_per_15;
public $knockdown_ratio;
public $knockouts;
public $decisions;
public $submissions;
/**
* Public constructor.
*
* @param Client $httpClient
*/
public function __construct(Client $httpClient) {
$this->http_client = $httpClient;
}
/**
* Get fighters url from name.
*
* @return string
*/
public function getFighterUrl() {
// Manual overrides for name problems go here.
if ($this->first_name == 'Khaos') {
$this->first_name = 'Kalinn';
}
if ($this->first_name == 'J') {
$this->first_name = 'JP';
$this->last_name = 'Buys';
}
if ($this->last_name == 'Mc Kee') {
$this->last_name = 'McKee';
}
if ($this->last_name == 'Mc Gee') {
$this->last_name = 'McGee';
}
if ($this->last_name == 'Mc Gregor') {
$this->last_name = 'mcgregor';
}
if ($this->last_name == "O&#039; Malley") {
$this->last_name = 'Omalley';
}
if ($this->first_name == "Don&#039;") {
$this->first_name = 'dontale';
$this->last_name = 'mayes';
}
if ($this->first_name == "Marc-") {
$this->first_name = 'Marc';
}
if ($this->first_name == "A") {
$this->first_name = 'AJ';
$this->last_name = 'Dobson';
}
if ($this->first_name == "C") {
$this->first_name = 'CB';
$this->last_name = 'Dollaway';
}
if ($this->last_name == "Della Maddalena") {
$this->last_name = 'Della';
}
if ($this->first_name == "Elizeudos") {
$this->first_name = 'elizeu';
$this->last_name = 'dos-santos';
}
if ($this->last_name == "La Flare") {
$this->last_name = 'laflare';
}
if ($this->first_name == "JoelÁlvarez") {
$this->first_name = 'Joel';
}
if ($this->last_name == "J Brown") {
$this->first_name = 'TJ';
$this->last_name = 'Brown';
}
if ($this->first_name == "Alexda") {
$this->first_name = "alex-da";
}
if ($this->last_name == "Mc Kinney") {
$this->last_name = "mckinney";
}
if ($this->last_name == "Van Camp") {
$this->last_name = "vancamp";
}
if ($this->last_name == "J Laramie") {
$this->first_name = "TJ";
$this->last_name = "Laramie";
}
if ($this->last_name == "Al- Qaisi") {
$this->last_name = "alqaisi";
}
if ($this->first_name == "Alatengheili") {
$this->first_name = "heili";
$this->last_name = "alateng";
}
if ($this->last_name == "J Dillashaw") {
$this->first_name = "TJ";
$this->last_name = "Dillashaw";
}
if ($this->first_name == "Andersondos") {
$this->first_name = "Anderson-dos";
}
if ($this->last_name == "Silvade Andrade") {
$this->last_name = "Silva-de-andrade";
}
if ($this->first_name == "Ode&#039;") {
$this->first_name = "ode";
}
if ($this->first_name == "Sumudaerji") {
$this->first_name = "su";
$this->last_name = "mudaerji";
}
$hyphens = str_replace(" ", "-", $this->last_name);
$suffix = $this->first_name . "-" . $hyphens;
if ($this->first_name == "Aoriqileng") {
$suffix = $this->first_name;
}
$url = "https://www.ufc.com/athlete/$suffix";
$trim = rtrim($url);
return $url;
}
/**
* Get contents of the fighter page.
*
* @return void
*/
public function getFighterPage() {
try {
$request = $this->http_client->request('GET', $this->getFighterUrl(), ['verify' => FALSE]);
$this->fighter_page = $request->getBody()->getContents();
} catch (\Exception $e) {
echo 'Caught exception: ', $e->getMessage(), "\n";
// exit();
}
/*
USE THIS FOR TESTING:
$player_url = "https://www.ufc.com/athlete/anthony-hamilton";
try {
$request = $this->http_client->request('GET', $player_url);
}
catch (\Exception $e) {
return FALSE;
}
$content = $request->getBody()->getContents();
*/
}
/**
* Get fighter age.
*
* @return void
*/
public function getAge() {
$pattern = '/<div class="field field--name-age(.*)<\/div>/';
preg_match($pattern, $this->fighter_page, $matches);
preg_match_all('!\d+!', $matches[0], $age);
$fighter_age = reset($age[0]);
$this->age = (float) $fighter_age;
}
public function getBio() {
$pattern = '/<div class="c-bio__text">[0-9]+\.[0-9]+/s';
preg_match_all($pattern, $this->fighter_page, $matches);
$matches = reset($matches);
// Get height.
$pattern = '/[0-9]+\.[0-9]+/';
preg_match($pattern, $matches[0], $height);
$this->height = reset($height);
// Get weight.
$pattern = '/[0-9]+\.[0-9]+/';
preg_match($pattern, $matches[1], $weight);
$this->weight = reset($weight);
// Get reach.
$pattern = '/[0-9]+\.[0-9]+/';
preg_match($pattern, $matches[2], $reach);
$this->reach = reset($reach);
// Get leg reach.
$pattern = '/[0-9]+\.[0-9]+/';
preg_match($pattern, $matches[3], $leg_reach);
$this->leg_reach = reset($leg_reach);
}
/**
* Extracts the fighter record.
*
* @return void
*/
public function getFighterRecord() {
$pattern = "/[0-9]+[-][0-9]+[-][0-9]+.\(W-L-D\)/";
preg_match($pattern, $this->fighter_page, $matches);
$r = reset($matches);
$r = str_replace(" (W-L-D)", "", $r);
$record_chunks = explode("-", $r);
$this->wins = $record_chunks[0];
$this->losses = $record_chunks[1];
$this->ties = $record_chunks[2];
}
/**
* Extracts the striking accuracy.
*
* @return void
*/
public function getStrikingAccuracy() {
$pattern = '/<title>Striking accuracy.(.*)<\/title>/';
preg_match($pattern, $this->fighter_page, $matches);
$this->striking_accuracy = str_replace('%', '', $matches[1]);
}
/**
* Extracts the grappling accuracy.
*
* @return void
*/
public function getGrapplingAccuracy() {
$pattern = '/<title>Grappling accuracy.(.*)<\/title>/';
preg_match($pattern, $this->fighter_page, $matches);
$this->grappling_accuracy = str_replace('%', '', $matches[1]);
}
/**
* Extracts averages from the statistics section.
*
* @return void
*/
public function getAverages() {
$pattern = '/<div class="c-stat-compare__group-1(.*)(<\/div>)/sU';
preg_match_all($pattern, $this->fighter_page, $matches);
$this->strikes_per_min = $this->extractNumber($matches[1][0]);
$this->takedowns_per_15 = $this->extractNumber($matches[1][1]);
$this->knockdown_ratio = $this->extractNumber($matches[1][3]);
$pattern = '/<div class="c-stat-compare__group-2(.*)(<\/div>)/sU';
preg_match_all($pattern, $this->fighter_page, $matches);
$this->absorbed_per_min = $this->extractNumber($matches[1][0]);
}
/**
* Extracts wins per type.
*
* @return void
*/
public function getWinsBreakdown() {
$pattern = '/<div class="c-stat-3bar__value">(.*)<\/div>/sU';
preg_match_all($pattern, $this->fighter_page, $matches);
$this->knockouts = $this->extractWinByType($matches[0][3]);
$this->decisions = $this->extractWinByType($matches[0][4]);
$this->submissions = $this->extractWinByType($matches[0][5]);
}
/**
* Helper to get number out of string.
*
* @param [type] $string
* @return void
*/
protected function extractNumber($string) {
$no_tags = strip_tags($string);
preg_match_all('!\d+!', $no_tags, $matches);
$number = implode('.', $matches[0]);
return $number;
}
/**
* Helper to extract number from number and percentage.
*
* @param [type] $string
* @return void
*/
protected function extractWinByType($string) {
$no_tags = strip_tags($string);
preg_match_all('!\d+!', $no_tags, $matches);
return $matches[0][0];
}
/**
* Creates a player node.
*
* @return void
*/
public function createPlayerNode() {
$division_id = self::transformWeightClass();
$title = $this->first_name . " " . $this->last_name;
$node = Node::create([
'type' => 'fighter',
'title' => $title,
'field_division' => self::getTermByName($division_id),
'field_first_name' => $this->first_name,
'field_last_name' => $this->last_name,
'field_wins' => $this->wins,
'field_losses' => $this->losses,
'field_ties' => $this->ties,
'field_player_photo' => [
'target_id' => $this->image_id,
],
'field_striking_accuracy' => $this->striking_accuracy,
'field_grappling_accuracy' => $this->grappling_accuracy,
'field_strikes_per_minute' => $this->strikes_per_min,
'field_absorbed_per_min' => $this->absorbed_per_min,
'field_takedowns_per_15' => $this->takedowns_per_15,
'field_knockdown_ratio' => $this->knockdown_ratio,
'field_knockouts' => $this->knockouts,
'field_decisions' => $this->decisions,
'field_submissions' => $this->submissions,
'field_age' => $this->age,
'field_reach' => $this->reach,
'field_leg_reach' => $this->leg_reach,
'field_height' => $this->height,
'field_weight' => $this->weight
]);
$node->status = 1;
$node->enforceIsNew();
$node->save();
}
/**
* Updates a player node.
*
* @param $nid
* @return void
*/
public function updatePlayerNode($nid) {
$node_storage = \Drupal::entityTypeManager()->getStorage('node');
$node = $node_storage->load($nid);
$node->field_wins = $this->wins;
$node->field_losses = $this->losses;
$node->field_ties = $this->ties;
$node->field_striking_accuracy = $this->striking_accuracy;
$node->field_grappling_accuracy = $this->grappling_accuracy;
$node->field_strikes_per_minute = $this->strikes_per_min;
$node->field_absorbed_per_min = $this->absorbed_per_min;
$node->field_takedowns_per_15 = $this->takedowns_per_15;
$node->field_knockdown_ratio = $this->knockdown_ratio;
$node->field_knockouts = $this->knockouts;
$node->field_decisions = $this->decisions;
$node->field_submissions = $this->submissions;
$node->field_age = $this->age;
$node->field_reach = $this->reach;
$node->field_leg_reach = $this->leg_reach;
$node->field_height = $this->height;
$node->field_weight = $this->weight;
$node->save();
}
/**
* Helper function to transform the weight class.
*
* @return void
*/
public function transformWeightClass() {
$weight_class = $this->class;
$stripped = str_replace("_", " ", $weight_class);
$upper = ucwords($stripped);
return $upper;
}
/**
* Helper function to retrieve taxo term by name.
*
* @param [type] $term_name
* @return void
*/
public function getTermByName($term_name) {
// Get taxonomy term storage.
$taxonomyStorage = \Drupal::service('entity.manager')->getStorage('taxonomy_term');
// Set name properties.
$properties['name'] = $term_name;
$properties['vid'] = 'ufc_divisions';
// Load taxonomy term by properties.
$terms = $taxonomyStorage->loadByProperties($properties);
$term = reset($terms);
if (!$term) {
$new_term = Term::create([
'name' => $term_name,
'vid' => 'ufc_divisions'
])->save();
return $new_term;
};
return $term->id();
}
/**
* Create media for the player headshot.
*
* @return void
*/
public function createMediaEntityFromImage() {
$file_name = self::extractFileName();
if (empty($file_name)) {
$rand = rand(0,100000000) . '.png';
$file_name = "default-headshot_$rand";
}
if (!empty($this->image)) {
$file_data = file_get_contents($this->image);
}
if (empty($file_data)) {
$file_data = file_get_contents("public://player-headshots/headshot-default.png");
}
$file = file_save_data(
$file_data,
"public://player-headshots/$file_name", FILE_EXISTS_RENAME);
$media_image = Media::create([
'bundle' => 'image',
'name' => $file_name,
'field_media_image' => [
'target_id' => $file->id(),
],
]);
$media_image->save();
$this->image_id = $media_image->id();
}
/**
* Helper to extract file name for images.
*
* @return void
*/
public function extractFilename() {
if (!empty($this->image)) {
preg_match('/[A-Z_0-9]*.png/', $this->image, $matches);
$file_name = reset($matches);
return $file_name;
}
return FALSE;
}
}

View File

@@ -0,0 +1,202 @@
<?php
namespace Drupal\ufc;
use Drupal\Core\Entity\EntityTypeManager;
use Drupal\media\Media;
use Drupal\ufc\Fighter;
use GuzzleHttp\Client;
class FighterImporter {
protected $http_client;
protected $entity_type_manager;
protected $fighters = [];
protected $weight_class;
// The base url for fighter lists.
const UFC_BASE = "https://www.ufc.com/athletes/all?filters%5B0%5D=status%3A23&filters%5B1%5D=weight_class%3";
// These are the filter values used to cycle through divisions.
protected $divisions = [
'heavyweight' => "A11",
'light_heavyweight' => "A13",
'middleweight' => "A14",
'welterweight' => "A15",
'lightweight' => "A12",
'featherweight' => "A9",
'bantamweight' => "A8",
'flyweight' => "A10",
'strawweight' => "A99",
];
/**
* Public constructor for Fighter Importer.
*
* @param Client $httpClient
* @param EntityTypeManager $entityTypeManager
*/
public function __construct(Client $httpClient, EntityTypeManager $entityTypeManager) {
$this->http_client = $httpClient;
$this->entity_type_manager = $entityTypeManager;
}
public function importFighters() {
// This will populate fighters array.
$fighters_by_div = self::getListOfCurrentFighters();
// Process each fighter into system.
foreach ($fighters_by_div as $division => $fighters) {
foreach ($fighters as $fighter_data) {
$fighter = new Fighter($this->http_client);
$fighter->first_name = $fighter_data['firstname'];
$fighter->last_name = $fighter_data['lastname'];
$fighter->image = $fighter_data['image'];
$fighter->class = $division;
$fighter->getFighterPage();
$fighter->getAge();
$fighter->getBio();
$fighter->getFighterRecord();
$fighter->getStrikingAccuracy();
$fighter->getGrapplingAccuracy();
$fighter->getAverages();
$fighter->getWinsBreakdown();
$fighter->createMediaEntityFromImage();
// Check if node exists, by title.
$title = $fighter->first_name . " " . $fighter->last_name;
$node_lookup = reset($this->entity_type_manager->getStorage('node')->loadByProperties(['title' => $title]));
if (!empty($node_lookup)) {
// Update instead of create.
$fighter->updatePlayerNode($node_lookup->id());
\Drupal::logger('ufc')->notice($fighter_data['firstname'] . " " . $fighter_data['lastname'] . " updated successfully.");
}
else {
echo "didnt find an existing player, creating new for " . $title;
$fighter->createPlayerNode();
\Drupal::logger('ufc')->notice($fighter_data['firstname'] . " " . $fighter_data['lastname'] . " imported successfully.");
}
}
}
}
/**
* Get list of current fighters.
*
* @return array $fighters
*/
public function getListOfCurrentFighters() {
foreach ($this->divisions as $division => $div_base_url) {
$division_url = self::UFC_BASE . $div_base_url;
$this->weight_class = $division;
echo "Starting import for " . $division . "\n";
self::loopThroughFighterPages($division_url);
}
return $this->fighters;
}
/**
* There is a pager, loop through to get all fighters.
*
* @param string $base_url
*/
public function loopThroughFighterPages($base_url) {
for ($i=0; $i<=20; $i++) {
$url = $base_url . "&page=$i";
$request = $this->http_client->request('GET', $url, ['verify' => false]);
$content = $request->getBody()->getContents();
$check = strpos($content, "No Result Found For");
if (!$check) {
echo "extracting fighters from page $i \n";
self::extractFighters($content);
continue;
}
break;
}
}
/**
* Extract fighters from a page.
*/
public function extractFighters($input) {
$pattern = '/<span class="c-listing-athlete__name">(.*)<\/span>/sU';
preg_match_all($pattern, $input, $matches);
$fighter_names = [];
foreach ($matches[1] as $fighter_name) {
$fighter_names[] = trim(html_entity_decode($fighter_name));
}
$fighter_names = array_unique($fighter_names);
foreach ($fighter_names as $name) {
$name_no_spaces = str_replace(" ", "", $name);
$class_exists = array_key_exists($this->weight_class, $this->fighters);
$fighter_exists = null;
if ($class_exists) {
$fighter_exists = array_key_exists($name_no_spaces, $this->fighters[$this->weight_class]);
}
if (!$fighter_exists) {
$chunks = preg_split('/(?=[A-Z])/', $name_no_spaces);
$first_name = $chunks[1];
$last_name_size = count($chunks);
switch($last_name_size) {
case 3:
$last_name = $chunks[2];
break;
case 4:
$last_name = $chunks[2] . " " . $chunks[3];
break;
case 5:
$last_name = $chunks[2] . " " . $chunks[3] . " " . $chunks[4];
break;
}
$this->fighters[$this->weight_class][$name_no_spaces]['firstname'] = $first_name;
$this->fighters[$this->weight_class][$name_no_spaces]['lastname'] = $last_name;
}
// Get image paths.
$pattern = '/<div class="c-listing-athlete__thumbnail(.*)<\/div>/sU';
preg_match_all($pattern, $input, $matches);
$images = [];
foreach ($matches[0] as $html_img) {
$images[] = $this->extractImageSource($html_img);
}
$name = strtoupper($last_name . '_' . $first_name);
$fighter_image = $this->getFighterImageFromList($images, $name);
$this->fighters[$this->weight_class][$name_no_spaces]['image'] = $fighter_image;
}
}
// Get the fighter image.
public function extractImageSource($source_html) {
$pattern = '/<img[^>]+src="([^">]+)"/';
preg_match_all($pattern, $source_html, $image);
return $image[1];
}
// Extract a specific fighter image from a list.
public function getFighterImageFromList($list, $fighter) {
foreach ($list as $url_arr) {
foreach ($url_arr as $url) {
if (strpos($url, $fighter) !== FALSE) {
return $url;
}
}
}
return FALSE;
}
}

View File

@@ -0,0 +1,54 @@
<?php
namespace Drupal\ufc\Form;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
/**
* Class SelfHealKickoffForm to start self heal in batches.
*
* @package Drupal\ufc\Form
*/
class SelfHealKickoffForm extends FormBase {
/**
* {@inheritdoc}
*/
public function getFormId() {
return 'self_heal_kickoff_form';
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$form['self_heal'] = array(
'#type' => 'submit',
'#value' => $this->t('Self Heal'),
);
return $form;
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$fights = \Drupal::service('entity_type.manager')->getStorage('node')->loadByProperties(['type' => 'fight']);
$batch = array(
'title' => t('Updating Fights...'),
'operations' => array(
array(
'\Drupal\ufc\FightPredictor::updatePredictionsBatched',
array($fights)
),
),
'finished' => '\Drupal\ufc\FightPredictor::fightUpdatedCallback',
);
batch_set($batch);
}
}