pgo/cases/mediawiki/TrainingCaseHandler.php (130 lines of code) (raw):
<?php
namespace mediawiki;
use SDK\Build\PGO\Abstracts;
use SDK\Build\PGO\Interfaces;
use SDK\Build\PGO\Config;
use SDK\Build\PGO\PHP;
use SDK\Exception;
use SDK\Build\PGO\Tool;
class TrainingCaseHandler extends Abstracts\TrainingCase implements Interfaces\TrainingCase
{
protected $base;
protected $nginx;
protected $php;
protected $max_runs = 4;
public function __construct(Config $conf, ?Interfaces\Server $nginx, ?Interfaces\Server\DB $srv_db)
{
if (!$nginx) {
throw new Exception("Invalid NGINX object");
}
$this->conf = $conf;
$this->base = $this->conf->getCaseWorkDir($this->getName());
$this->nginx = $nginx;
$this->php = $nginx->getPhp();
}
public function getName() : string
{
return __NAMESPACE__;
}
public function getJobFilename() : string
{
return $this->conf->getJobDir() . DIRECTORY_SEPARATOR . $this->getName() . ".txt";
}
protected function getToolFn(string $what) : string
{
$ret = NULL;
if ("install" == $what) {
$ret = $this->conf->getCaseWorkDir($this->getName()) . DIRECTORY_SEPARATOR . "maintenance" . DIRECTORY_SEPARATOR . "install.php";
}
return $ret;
}
protected function setupDist() : void
{
$php = new PHP\CLI($this->conf);
$port = $this->getHttpPort();
$host = $this->getHttpHost();
$vars = array(
$this->conf->buildTplVarName($this->getName(), "docroot") => str_replace("\\", "/", $this->base),
);
$tpl_fn = $this->conf->getCasesTplDir($this->getName()) . DIRECTORY_SEPARATOR . "nginx.partial.conf";
$this->nginx->addServer($tpl_fn, $vars);
$settings = $this->conf->getCaseWorkDir($this->getName()) . DIRECTORY_SEPARATOR . "LocalSettings.php";
if (is_file($settings)) {
unlink($settings);
}
$site_adm = trim(shell_exec("pwgen -1 -s 8"));
$this->conf->setSectionItem($this->getName(), "site_admin_user", $site_adm);
$site_pw = trim(shell_exec("pwgen -1 -s 8"));
$this->conf->setSectionItem($this->getName(), "site_admin_pass", $site_pw);
$db_dir = $this->conf->getCaseWorkDir($this->getName()) . DIRECTORY_SEPARATOR . "database";
$nom = $this->getName();
$db_dir = $this->conf->getCaseWorkDir($this->getName()) . DIRECTORY_SEPARATOR . "database";
if (!is_dir($db_dir)) {
mkdir($db_dir);
}
$cmd = $this->getToolFn("install") . " --dbtype=sqlite --dbpath=$db_dir --pass=$site_pw --server=http://$host:$port/ $nom $site_adm";
echo "$cmd\n";
$php->exec($cmd);
}
public function setupUrls()
{
$this->nginx->up();
$url = "http://" . $this->getHttpHost() . ":" . $this->getHttpPort();
$s = file_get_contents($url);
echo "Generating training urls.\n";
$lst = array();
if (preg_match_all(", href=\"([^\"]+)\",", $s, $m)) {
foreach ($m[1] as $u) {
if ("/" == $u[0] && "/" != $u[1] && !in_array(substr($u, -3), array("css", "xml", "ico"))) {
$u = str_replace(
array("&"),
array("&"),
$u
);
$ur = "http://" . $this->getHttpHost() . ":" . $this->getHttpPort() . $u;
if (!in_array($ur, $lst) && $this->probeUrl($ur)) {
$lst[] = $ur;
}
}
}
}
$this->nginx->down(true);
if (empty($lst)) {
printf("\033[31m WARNING: Training URL list is empty, check the regex and the possible previous error messages!\033[0m\n");
}
$fn = $this->getJobFilename();
$s = implode("\n", $lst);
if (strlen($s) !== file_put_contents($fn, $s)) {
throw new Exception("Couldn't write '$fn'.");
}
}
public function prepareInit(Tool\PackageWorkman $pw, bool $force = false) : void
{
$url = $this->conf->getSectionItem($this->getName(), "mediawiki_zip_url");
$pw->fetchAndUnzip($url, "mediawiki.zip", $this->conf->getCaseWorkDir(), $this->getName(), $force);
$php = new PHP\CLI($this->conf);
$lock = $this->conf->getCaseWorkDir($this->getName()) . DIRECTORY_SEPARATOR . "composer.lock";
if (!file_exists($lock) || $force) {
$composer = $this->conf->getToolsDir() . DIRECTORY_SEPARATOR . "composer.phar";
$composer_cmd = file_exists($lock) ? "update" : "install";
$cmd = $composer . " $composer_cmd --no-dev --working-dir=" . $this->conf->getCaseWorkDir($this->getName());
$php->exec($cmd);
}
$skin_url = "https://github.com/wikimedia/mediawiki-skins-Vector/archive/master.zip";
$skin_path = $this->conf->getCaseWorkDir($this->getName()) . DIRECTORY_SEPARATOR . "skins" . DIRECTORY_SEPARATOR . "Vector";
if (!file_exists($skin_path . DIRECTORY_SEPARATOR . "SkinVector.php")) {
if (is_dir($skin_path)) {
rmdir($skin_path);
}
$pw->fetchAndUnzip($skin_url, "mediawiki_skin.zip", dirname($skin_path), "Vector", $force);
}
}
public function init() : void
{
echo "Initializing " . $this->getName() . ".\n";
$this->setupDist();
$this->setupUrls();
echo $this->getName() . " initialization done.\n";
echo $this->getName() . " site configured to run under " . $this->getHttpHost() . ":" . $this->getHttpPort() . "\n";
}
}