mirror of
https://github.com/e107inc/e107.git
synced 2025-01-17 20:58:30 +01:00
4c56593f81
Small corrections
1396 lines
42 KiB
PHP
Executable File
1396 lines
42 KiB
PHP
Executable File
<?php
|
|
/*
|
|
* e107 website system
|
|
*
|
|
* Copyright (C) 2008-2016 e107 Inc (e107.org)
|
|
* Released under the terms and conditions of the
|
|
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt)
|
|
*
|
|
* Administration - File inspector
|
|
*
|
|
*/
|
|
ob_implicit_flush(true);
|
|
|
|
if(!empty($_GET['action']) && $_GET['action'] === 'progress' && !empty($_GET['scan']))
|
|
{
|
|
$content = file_inspector::readScanProgress($_GET['scan']);
|
|
echo $content;
|
|
exit;
|
|
}
|
|
|
|
|
|
require_once(__DIR__.'/../class2.php');
|
|
|
|
|
|
|
|
e107::coreLan('fileinspector', true);
|
|
|
|
if(!getperms('Y'))
|
|
{
|
|
e107::redirect('admin');
|
|
exit;
|
|
}
|
|
|
|
set_time_limit(18000);
|
|
$e_sub_cat = 'fileinspector';
|
|
|
|
if (!empty($_GET['regex']))
|
|
{
|
|
$css = ".f { padding: 1px 0px 1px 8px; vertical-align: bottom; width: 90% }\n";
|
|
}
|
|
else
|
|
{
|
|
$css = ".f { padding: 1px 0px 1px 8px; vertical-align: bottom; width: 90%; white-space: nowrap }\n";
|
|
}
|
|
|
|
$css .= ".d { margin: 2px 0px 1px 8px; cursor: default; white-space: nowrap }
|
|
.s { padding: 1px 8px 1px 0px; vertical-align: bottom; width: 10%; white-space: nowrap }
|
|
.t { margin-top: 1px; width: 100%; border-collapse: collapse; border-spacing: 0px }
|
|
.w { padding: 1px 0px 1px 8px; vertical-align: bottom; width: 90% }
|
|
.i { width: 16px; height: 16px }
|
|
.e { width: 9px; height: 9px }
|
|
i.fa-folder-open-o, i.fa-times-circle-o { cursor:pointer }
|
|
span.tree-node { cursor: pointer }
|
|
|
|
";
|
|
|
|
e107::css('inline', $css);
|
|
|
|
$js = "
|
|
c = new Image(); c = '".SITEURLBASE.e_IMAGE_ABS."fileinspector/contract.png';
|
|
e = '".SITEURLBASE.e_IMAGE_ABS."fileinspector/expand.png';
|
|
function ec(ecid) {
|
|
icon = document.getElementById('e_' + ecid).src;
|
|
if(icon.indexOf('expand.png') !== -1) {
|
|
document.getElementById('e_' + ecid).src = c;
|
|
} else {
|
|
document.getElementById('e_' + ecid).src = e;
|
|
}
|
|
div = document.getElementById('d_' + ecid).style;
|
|
if(div.display == 'none') {
|
|
div.display = '';
|
|
} else {
|
|
div.display = 'none';
|
|
}
|
|
}
|
|
var hideid = 'initial';
|
|
function sh(showid) {
|
|
if(hideid != showid) {
|
|
show = document.getElementById(showid).style;
|
|
hide = document.getElementById(hideid).style;
|
|
show.display = '';
|
|
hide.display = 'none';
|
|
hideid = showid;
|
|
}
|
|
}
|
|
";
|
|
|
|
|
|
e107::js('footer-inline', $js);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class fileinspector_admin extends e_admin_dispatcher
|
|
{
|
|
|
|
protected $modes = array(
|
|
|
|
'main' => array(
|
|
'controller' => 'fileinspector_ui',
|
|
'path' => null,
|
|
'ui' => 'fileinspector_form_ui',
|
|
'uipath' => null
|
|
),
|
|
|
|
|
|
);
|
|
|
|
protected $adminMenu = array(
|
|
|
|
'main/setup' => array('caption'=> LAN_CONFIGURE, 'perm' => 'P'),
|
|
// 'main/run' => array('caption'=> FR_LAN_2, 'perm' => 'P'),
|
|
);
|
|
|
|
protected $adminMenuAliases = array(
|
|
'main/edit' => 'main/list'
|
|
);
|
|
|
|
protected $menuTitle = FC_LAN_1;
|
|
|
|
protected $adminMenuIcon = 'e-fileinspector-24';
|
|
|
|
|
|
|
|
function init()
|
|
{
|
|
|
|
|
|
if(!empty($_GET['viewerror']))
|
|
{
|
|
$file = e107::getSession()->get('fileinspector_error_log_'. $_GET['viewerror']);
|
|
|
|
if(!empty($file))
|
|
{
|
|
$contents = file_get_contents(e_BASE.$file);
|
|
echo "<pre style='color:silver;background: #000'>".$contents."</pre>";
|
|
|
|
}
|
|
|
|
exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!empty($_GET['action']) && $_GET['action'] === 'begin')
|
|
{
|
|
/** @var file_inspector $fi */
|
|
$fi = e107::getSingleton('file_inspector');
|
|
$fi->scan_results();
|
|
|
|
exit();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
class fileinspector_ui extends e_admin_ui
|
|
{
|
|
|
|
protected $pluginTitle = FC_LAN_1;
|
|
protected $pluginName = 'core';
|
|
protected $eventName = 'fileinspector';
|
|
protected $table = '';
|
|
protected $pid = '';
|
|
protected $perPage = 10;
|
|
protected $batchDelete = true;
|
|
protected $batchCopy = true;
|
|
// protected $sortField = 'somefield_order';
|
|
// protected $orderStep = 10;
|
|
// protected $tabs = array('Tabl 1','Tab 2'); // Use 'tab'=>0 OR 'tab'=>1 in the $fields below to enable.
|
|
protected $listQry = ""; // Example Custom Query. LEFT JOINS allowed. Should be without any Order or Limit.
|
|
protected $listOrder = '';
|
|
protected $fields = array ();
|
|
protected $fieldpref = array();
|
|
protected $prefs = array();
|
|
|
|
protected $fi;
|
|
|
|
public function init()
|
|
{
|
|
//
|
|
}
|
|
|
|
public function SetupPage()
|
|
{
|
|
/** @var file_inspector */
|
|
$fi =e107::getSingleton('file_inspector');
|
|
return $fi->scan_config();
|
|
}
|
|
|
|
public function RunPage()
|
|
{
|
|
$this->addTitle(LAN_CONFIGURE);
|
|
$this->addTitle(LAN_RUN);
|
|
|
|
$frm = $this->getUI();
|
|
|
|
unset($_GET['mode'],$_GET['action']);
|
|
|
|
$source = e_SELF."?mode=main&action=begin&".http_build_query($_GET);
|
|
$target = '#results-container';
|
|
$interval = 500;
|
|
|
|
$text = $frm->open('runit');
|
|
$text .= $frm->progressBar('inspector-progress', 0);
|
|
|
|
// $text .= '<button id="start-render" type="button" data-loading-icon="fa-spinner" data-loading-target="#start-render" class="e-ajax btn-sm btn btn-primary" data-src="'.$source.'" data-target="#results-container">Other</button>';
|
|
|
|
|
|
$text .= '<a id="start-render" class="btn btn-primary e-progress e-ajax " data-src="'.$source.'" data-target="'.$target.'" data-loading-icon="fa-spinner" data-progress-interval="'.$interval.'" data-progress-target="inspector-progress" data-progress="' . e_SELF.'?mode=main&action=progress&scan='.filter_var($_GET['scan']).'" data-progress-mode="0" data-progress-show="1" data-loading-target="#fi-loading-target" ><span id="fi-loading-target"></span> '.FR_LAN_33.'</a>';
|
|
$text .= ' <a data-progress-target="inspector-progress" class="btn btn-danger e-progress-cancel" >'.LAN_CANCEL.'</a>';
|
|
|
|
|
|
$text .= $frm->close();
|
|
$text .= "<div id='results-container'></div>";
|
|
|
|
|
|
|
|
return $text;
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
class fileinspector_form_ui extends e_admin_form_ui
|
|
{
|
|
|
|
}
|
|
|
|
|
|
new fileinspector_admin();
|
|
|
|
require_once(e_ADMIN."auth.php");
|
|
|
|
e107::getAdminUI()->runPage();
|
|
|
|
require_once(e_ADMIN."footer.php");
|
|
|
|
|
|
|
|
|
|
|
|
class file_inspector {
|
|
const SCAN_ID_PREFIX = 'e107-file-inspector-scan-';
|
|
|
|
/** @var e_file_inspector */
|
|
private $coreImage;
|
|
private $coreImageVersion;
|
|
|
|
private $root_dir;
|
|
private $files = array();
|
|
private $fileSizes = array();
|
|
private $count = array();
|
|
/** @deprecated What's this? */
|
|
var $results = 0;
|
|
private $totalFiles = 0;
|
|
private $progress_units = 0;
|
|
private $progressPercentage = 0;
|
|
private $langs = array();
|
|
private $lang_short = array();
|
|
private $iconTag = array();
|
|
|
|
private $options = array(
|
|
'core' => '',
|
|
'type' => 'tree',
|
|
'missing' => 0,
|
|
'noncore' => 9,
|
|
'oldcore' => 0,
|
|
'integrity' => 1,
|
|
'regex' => 0,
|
|
'mod' => '',
|
|
'num' => 0,
|
|
'line' => 0,
|
|
'scan' => null // progress identifier
|
|
);
|
|
/**
|
|
* @var array
|
|
*/
|
|
private $glyph;
|
|
|
|
function setOptions($post)
|
|
{
|
|
foreach($this->options as $k=>$v)
|
|
{
|
|
if(isset($post[$k]))
|
|
{
|
|
$this->options[$k] = $post[$k];
|
|
}
|
|
}
|
|
}
|
|
|
|
function __construct()
|
|
{
|
|
$lng = e107::getLanguage();
|
|
$langs = $lng->installed();
|
|
|
|
$this->setOptions($_GET);
|
|
|
|
$lang_short = array();
|
|
|
|
foreach($langs as $k=>$val)
|
|
{
|
|
if($val == "English") // Core release language, so ignore it.
|
|
{
|
|
unset($langs[$k]);
|
|
continue;
|
|
}
|
|
|
|
$lang_short[] = $lng->convert($val);
|
|
}
|
|
|
|
$this->langs = $langs;
|
|
$this->lang_short = $lang_short;
|
|
|
|
$this->glyph = array(
|
|
'folder_close' => array('<i class="fa fa-times-circle-o"></i>'),
|
|
'folder_up' => array('<i class="fa fa-folder-open-o"></i>'),
|
|
'folder_root' => array('<i class="fa fa-folder-o"></i>'),
|
|
|
|
'warning' => array('<i class="fa fa-exclamation-triangle text-warning" ></i>'),
|
|
'info' => array('<i class="fa fa-info-circle text-primary" ></i>'),
|
|
'fileinspector' => array('<i class="fa fa-folder text-success" style="color:#F6EDB0;"></i>'),
|
|
|
|
'folder' => array('<i class="fa fa-folder text-success" style="color:#F6EDB0;"></i>'),
|
|
'folder_check' => array('<i class="fa fa-folder text-success" style="color:#F6EDB0" ></i>', FC_LAN_24 ),
|
|
'folder_fail' => array('<i class="fa fa-folder text-danger" ></i>', FC_LAN_25 ),
|
|
'folder_uncalc' => array('<i class="fa fa-folder-o" ></i>', FC_LAN_24 ),
|
|
'folder_missing' => array('<i class="fa fa-folder-o text-danger" ></i>', FC_LAN_26 ),
|
|
'folder_warning' => array('<i class="fa fa-folder text-warning" ></i>'),
|
|
'folder_old' => array('<i class="fa fa-folder-o text-warning" ></i>', FC_LAN_27 ),
|
|
'folder_old_dir' => array('<i class="fa fa-folder-o text-warning" ></i>'),
|
|
'folder_unknown' => array('<i class="fa fa-folder-o text-primary" ></i>', FC_LAN_28 ),
|
|
|
|
'file_check' => array('<i class="fa fa-file text-success" style="color:#F6EDB0" ></i>', FC_LAN_29),
|
|
'file_core' => array('<i class="fa fa-file-o text-success" style="color:#F6EDB0" ></i>', FC_LAN_30),
|
|
'file_fail' => array('<i class="fa fa-file text-danger" ></i>', FC_LAN_31 ),
|
|
'file_missing' => array('<i class="fa fa-file-o text-danger" ></i>', FC_LAN_32 ),
|
|
'file_old' => array('<i class="fa fa-file-o text-warning" ></i>', FC_LAN_33 ),
|
|
'file_uncalc' => array('<i class="fa fa-file-o " ></i>', FC_LAN_34 ),
|
|
'file_warning' => array('<i class="fa fa-file text-warning" ></i>', FC_LAN_35 ),
|
|
'file_unknown' => array('<i class="fa fa-file-o text-primary" ></i>', FC_LAN_36 ),
|
|
);
|
|
|
|
foreach($this->glyph as $k=>$v)
|
|
{
|
|
$this->iconTag[$k] = $this->glyph[$k][0];
|
|
}
|
|
|
|
$e107 = e107::getInstance();
|
|
$this->coreImage = e107::getFileInspector('core');
|
|
$this->coreImageVersion = $this->coreImage->getCurrentVersion();
|
|
|
|
$this->root_dir = $e107 -> file_path;
|
|
|
|
if(substr($this->root_dir, -1) == '/')
|
|
{
|
|
$this->root_dir = substr($this->root_dir, 0, -1);
|
|
}
|
|
|
|
if(isset($_POST['core']) && $_POST['core'] == 'integrity_fail_only')
|
|
{
|
|
$_POST['integrity'] = TRUE;
|
|
}
|
|
|
|
if(MAGIC_QUOTES_GPC && vartrue($_POST['regex']))
|
|
{
|
|
$_POST['regex'] = stripslashes($_POST['regex']);
|
|
}
|
|
|
|
if(!empty($_POST['regex']))
|
|
{
|
|
if($_POST['core'] == 'fail')
|
|
{
|
|
$_POST['core'] = 'all';
|
|
}
|
|
|
|
$_POST['missing'] = 0;
|
|
$_POST['integrity'] = 0;
|
|
}
|
|
|
|
self::pruneOldProgressFiles();
|
|
}
|
|
|
|
|
|
private function opt($key)
|
|
{
|
|
return $this->options[$key];
|
|
}
|
|
|
|
|
|
// Find the Total number of core files before scanning begins.
|
|
private function countFiles()
|
|
{
|
|
return $this->totalFiles = iterator_count($this->coreImage->getPathIterator($this->coreImageVersion));
|
|
}
|
|
|
|
|
|
function getLegend()
|
|
{
|
|
return $this->glyph;
|
|
}
|
|
|
|
|
|
function renderHelp()
|
|
{
|
|
$text = "<table>";
|
|
|
|
foreach($this->iconTag as $k=>$v)
|
|
{
|
|
$text .= "<tr><td>".$v."</td><td>".$k."</td></tr>";
|
|
|
|
}
|
|
$text .= "</table>";
|
|
|
|
return $text;
|
|
// echo $text;
|
|
}
|
|
|
|
|
|
public function scan_config()
|
|
{
|
|
$frm = e107::getForm();
|
|
$pref = e107::pref('core');
|
|
|
|
if($_GET['mode'] == 'run')
|
|
{
|
|
return;
|
|
}
|
|
|
|
$tab = array();
|
|
|
|
$head = "<div>
|
|
<form action='".e_SELF."' method='get' id='scanform'>";
|
|
|
|
$text = "
|
|
<table class='table adminform'>";
|
|
|
|
/* $text .= "
|
|
<tr>
|
|
<td class='fcaption' colspan='2'>".LAN_OPTIONS."</td>
|
|
</tr>";*/
|
|
|
|
$coreOpts = array('integrity_fail_only'=>FC_LAN_6, 'all'=>LAN_ALL, 'none'=> LAN_NONE);
|
|
|
|
$text .= "<tr>
|
|
<td style='width: 35%'>
|
|
".LAN_SHOW." ".FC_LAN_5.":
|
|
</td>
|
|
<td colspan='2' style='width: 65%'>".$frm->select('core',$coreOpts,varset($_POST['core']))." </td>
|
|
</tr>";
|
|
|
|
|
|
$dispOpt = array('tree'=>FC_LAN_15, 'list'=>LAN_LIST);
|
|
$text .= "<tr>
|
|
<td style='width: 35%'>
|
|
".FC_LAN_14.":
|
|
</td>
|
|
<td colspan='2' style='width: 65%'>".$frm->select('type', $dispOpt, varset($_POST['type']))." </td>
|
|
</td>
|
|
</tr>";
|
|
|
|
|
|
$text .= "<tr>
|
|
<td style='width: 35%'>
|
|
".LAN_SHOW." ".FC_LAN_13.":
|
|
</td>
|
|
<td colspan='2' style='width: 65%'>
|
|
<input type='radio' name='missing' value='1'".((varset($_POST['missing']) == '1' || !isset($_POST['missing'])) ? " checked='checked'" : "")." /> ".LAN_YES."
|
|
<input type='radio' name='missing' value='0'".(varset($_POST['missing']) == '0' ? " checked='checked'" : "")." /> ".LAN_NO."
|
|
</td>
|
|
</tr>";
|
|
|
|
$text .= "<tr>
|
|
<td style='width: 35%'>
|
|
".LAN_SHOW." ".FC_LAN_7.":
|
|
</td>
|
|
<td colspan='2' style='width: 65%'>
|
|
<input type='radio' name='noncore' value='1'".((varset($_POST['noncore']) == '1' || !isset($_POST['noncore'])) ? " checked='checked'" : "")." /> ".LAN_YES."
|
|
<input type='radio' name='noncore' value='0'".(varset($_POST['noncore']) == '0' ? " checked='checked'" : "")." /> ".LAN_NO."
|
|
</td>
|
|
</tr>";
|
|
|
|
$text .= "<tr>
|
|
<td style='width: 35%'>
|
|
".LAN_SHOW." ".FC_LAN_21.":
|
|
</td>
|
|
<td colspan='2' style='width: 65%'>
|
|
<input type='radio' name='oldcore' value='1'".((varset($_POST['oldcore']) == '1' || !isset($_POST['oldcore'])) ? " checked='checked'" : "")." /> ".LAN_YES."
|
|
<input type='radio' name='oldcore' value='0'".(varset($_POST['oldcore']) == '0' ? " checked='checked'" : "")." /> ".LAN_NO."
|
|
</td>
|
|
</tr>";
|
|
|
|
/*
|
|
$text .= "<tr>
|
|
<td style='width: 35%'>
|
|
".FC_LAN_8.":
|
|
</td>
|
|
<td style='width: 65%; vertical-align: top'>
|
|
<input type='radio' name='integrity' value='1'".(($_POST['integrity'] == '1' || !isset($_POST['integrity'])) ? " checked='checked'" : "")." /> ".LAN_YES."
|
|
<input type='radio' name='integrity' value='0'".($_POST['integrity'] == '0' ? " checked='checked'" : "")." /> ".LAN_NO."
|
|
</td></tr>";
|
|
*/
|
|
|
|
$text .= "</table>";
|
|
|
|
$tab['basic'] = array('caption'=>LAN_OPTIONS, 'text'=>$text);
|
|
|
|
if($pref['developer']) {
|
|
|
|
$text2 = "<table class='table adminlist'>";
|
|
/* $text2 .= "<tr>
|
|
<td class='fcaption' colspan='2'>".FC_LAN_17."</td>
|
|
</tr>";*/
|
|
|
|
$text2 .= "<tr>
|
|
<td style='width: 35%'>
|
|
".FC_LAN_18.":
|
|
</td>
|
|
<td colspan='2' style='width: 65%'>
|
|
#<input class='tbox' type='text' name='regex' size='40' value='".htmlentities($_POST['regex'], ENT_QUOTES)."' />#<input class='tbox' type='text' name='mod' size='5' value='".$_POST['mod']."' />
|
|
</td>
|
|
</tr>";
|
|
|
|
$text2 .= "<tr>
|
|
<td style='width: 35%'>
|
|
".FC_LAN_19.":
|
|
</td>
|
|
<td colspan='2' style='width: 65%'>
|
|
<input type='checkbox' name='num' value='1'".(($_POST['num'] || !isset($_POST['num'])) ? " checked='checked'" : "")." />
|
|
</td>
|
|
</tr>";
|
|
|
|
$text2 .= "<tr>
|
|
<td style='width: 35%'>
|
|
".FC_LAN_20.":
|
|
</td>
|
|
<td colspan='2' style='width: 65%'>
|
|
<input type='checkbox' name='line' value='1'".(($_POST['line'] || !isset($_POST['line'])) ? " checked='checked'" : "")." />
|
|
</td>
|
|
</tr>";
|
|
|
|
$text2 .= "
|
|
</table>";
|
|
|
|
$tab['advanced'] = array('caption'=>FC_LAN_17, 'text'=>$text2);
|
|
}
|
|
|
|
$tabText = e107::getForm()->tabs($tab);
|
|
|
|
|
|
$foot = "
|
|
<div class='buttons-bar center'>
|
|
".$frm->admin_button('scan', md5(time()), 'other', LAN_GO).
|
|
$frm->hidden('mode','main').
|
|
$frm->hidden('action','run')."
|
|
</div>
|
|
</form>
|
|
</div>";
|
|
|
|
$text = $head.$tabText.$foot;
|
|
|
|
return $text;
|
|
// $ns->tablerender(FC_LAN_1, $text);
|
|
|
|
}
|
|
|
|
/**
|
|
* @param $baseDir string Absolute path to the directory to inspect
|
|
*/
|
|
protected function inspect($baseDir)
|
|
{
|
|
$this->progress_units = 0;
|
|
$this->totalFiles = 1;
|
|
$this->sendProgress(0);
|
|
$this->totalFiles = iterator_count(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($baseDir))) * 2;
|
|
$this->inspect_existing($baseDir);
|
|
$this->inspect_missing(array_keys($this->files));
|
|
|
|
}
|
|
|
|
private function inspect_existing($baseDir)
|
|
{
|
|
$absoluteBase = realpath($baseDir);
|
|
if (!is_dir($absoluteBase)) return;
|
|
|
|
$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($baseDir));
|
|
foreach ($iterator as $file)
|
|
{
|
|
$this->sendProgress(1);
|
|
if ($file->isDir()) continue;
|
|
|
|
$absolutePath = $file->getRealPath();
|
|
$relativePath = preg_replace("/^" . preg_quote($absoluteBase . "/", "/") . "/", "", $absolutePath);
|
|
|
|
if (empty($relativePath) || $relativePath == $absolutePath) continue;
|
|
|
|
$this->files[$relativePath] = $this->coreImage->validate($relativePath);
|
|
$this->fileSizes[$relativePath] = filesize($absolutePath);
|
|
$this->updateFileSizeCounter($absolutePath, $this->files[$relativePath]);
|
|
}
|
|
}
|
|
|
|
private function inspect_missing($existingPaths)
|
|
{
|
|
$dbIterator = $this->coreImage->getPathIterator($this->coreImageVersion);
|
|
$dbPaths = iterator_to_array($dbIterator);
|
|
$dbPaths = array_map(function ($defaultPath)
|
|
{
|
|
return $this->coreImage->defaultPathToCustomPath($defaultPath);
|
|
}, $dbPaths);
|
|
$missingPaths = array_diff($dbPaths, $existingPaths);
|
|
foreach ($missingPaths as $relativePath)
|
|
{
|
|
$this->files[$relativePath] = $this->coreImage->validate($relativePath);
|
|
}
|
|
}
|
|
|
|
private function updateFileSizeCounter($absolutePath, $validationCode)
|
|
{
|
|
$status = e_file_inspector::getStatusForValidationCode($validationCode);
|
|
$category = $this->statusToLegacyCountCategory($status);
|
|
$fileSize = filesize($absolutePath);
|
|
$this->count[$category]['size'] += $fileSize;
|
|
|
|
if ($validationCode & e_file_inspector::VALIDATED_PATH_VERSION &&
|
|
$validationCode & e_file_inspector::VALIDATED_FILE_EXISTS)
|
|
$this->count['core']['size'] += $fileSize;
|
|
}
|
|
|
|
private function statusToLegacyCountCategory($status)
|
|
{
|
|
$category = $status;
|
|
switch ($status)
|
|
{
|
|
case 'check':
|
|
$category = 'pass';
|
|
break;
|
|
case 'uncalc':
|
|
$category = 'uncalculable';
|
|
break;
|
|
case 'old':
|
|
$category = 'deprecated';
|
|
break;
|
|
}
|
|
return $category;
|
|
}
|
|
|
|
/**
|
|
* @return string HTML output of the validated directory structure
|
|
*/
|
|
private function generateScanResultsHtml()
|
|
{
|
|
$nestedFiles = [];
|
|
foreach ($this->files as $relativePath => $validation)
|
|
{
|
|
if ($this->displayAllowed($validation))
|
|
self::array_set($nestedFiles, $relativePath, $validation);
|
|
}
|
|
return $this->generateDirectoryHtml([SITENAME => $nestedFiles]);
|
|
}
|
|
|
|
|
|
private function renderFileName($tree, $fileName, $relativePath,$rowId)
|
|
{
|
|
|
|
|
|
|
|
if($fileName === 'error_log')
|
|
{
|
|
$hash = md5($relativePath);
|
|
e107::getSession()->set('fileinspector_error_log_'. $hash, $relativePath);
|
|
|
|
|
|
return "<a class='e-modal' data-modal-caption=\"".$relativePath."\" href='fileinspector.php?iframe=1&viewerror=".$hash."'>".$fileName."</a>";
|
|
}
|
|
|
|
if (!is_array($tree[$fileName]))
|
|
{
|
|
return $fileName;
|
|
}
|
|
|
|
|
|
return "<span class='tree-node' onclick=\"ec('$rowId')\">".$fileName."</span>";
|
|
}
|
|
|
|
private function generateDirectoryHtml($tree, $level = 0, $parentPath = '')
|
|
{
|
|
$html = '';
|
|
|
|
$this->sortAscDirectoriesFirst($tree);
|
|
$hide = $level;
|
|
foreach ($tree as $fileName => $validationCode)
|
|
{
|
|
$this->sendProgress(1);
|
|
$relativePath = ltrim("$parentPath/$fileName", '/');
|
|
if ($level === 0) $relativePath = '';
|
|
$rowId = str_replace(" ", "%20", $relativePath);
|
|
list($icon, $title) = $this->getGlyphForValidationCode($validationCode);
|
|
$html .= "<div class=\"d\" title=\"$title\" style=\"margin-left: " . ($level * 8) . "px\">";
|
|
$html .= "<span class='tree-node' onclick=\"ec('$rowId')\">";
|
|
$html .= $this->getTreeActionImageForFile($tree, $fileName, $rowId, $hide);
|
|
$html .= "</span> <span onclick=\"sh('f_$rowId')\">" .
|
|
$icon.
|
|
" ".$this->renderFileName($tree, $fileName,$relativePath, $rowId)."</span>";
|
|
if (is_array($validationCode))
|
|
{
|
|
$html .= "<div id=\"d_$rowId\" " . ($hide ? "style=\"display:none\"" : "") . ">";
|
|
$html .= $this->generateDirectoryHtml($validationCode, $level + 1, $relativePath);
|
|
$html .= "</div>";
|
|
}
|
|
else
|
|
{
|
|
$oldVersion = $this->getOldVersionOfPath($relativePath, $validationCode);
|
|
$html .= '<span style="float:right">';
|
|
$html .= isset($this->fileSizes[$relativePath]) ? $this->parsesize($this->fileSizes[$relativePath]) : '';
|
|
$html .= $oldVersion ? " (v$oldVersion)" : "";
|
|
$html .= '</span>';
|
|
}
|
|
$html .= "</div>";
|
|
}
|
|
|
|
return $html;
|
|
}
|
|
|
|
private function sortAscDirectoriesFirst(array &$tree)
|
|
{
|
|
return uksort($tree, function ($a, $b) use ($tree)
|
|
{
|
|
if (is_array($tree[$a]) && !is_array($tree[$b])) return -1;
|
|
elseif (!is_array($tree[$a]) && is_array($tree[$b])) return 1;
|
|
return $a > $b;
|
|
});
|
|
}
|
|
|
|
private function getTreeActionImageForFile($tree, $fileName, $id, $hide = false)
|
|
{
|
|
if (!is_array($tree[$fileName]))
|
|
{
|
|
$actionImage = 'blank';
|
|
$actionAlt = ' ';
|
|
}
|
|
elseif ($hide)
|
|
{
|
|
$actionImage = 'expand';
|
|
$actionAlt = '+';
|
|
}
|
|
else
|
|
{
|
|
$actionImage = 'contract';
|
|
$actionAlt = '-';
|
|
}
|
|
|
|
return "<img id='e_$id' class='e' src='".e_IMAGE."fileinspector/$actionImage.png' alt='$actionAlt' width='15' />";
|
|
}
|
|
|
|
private function getGlyphForValidationCode($validationCodeOrArray)
|
|
{
|
|
if (is_array($validationCodeOrArray)) return $this->getWorstGlyphForFolder($validationCodeOrArray);
|
|
return $this->glyph['file_' . e_file_inspector::getStatusForValidationCode($validationCodeOrArray)];
|
|
}
|
|
|
|
private function getStatusRank($status)
|
|
{
|
|
$rank = PHP_INT_MIN;
|
|
switch ($status)
|
|
{
|
|
case 'unknown':
|
|
$rank = -2;
|
|
break;
|
|
case 'uncalc':
|
|
$rank = -1;
|
|
break;
|
|
case 'check':
|
|
$rank = 0;
|
|
break;
|
|
case 'missing':
|
|
$rank = 1;
|
|
break;
|
|
case 'old':
|
|
$rank = 2;
|
|
break;
|
|
case 'fail':
|
|
$rank = 3;
|
|
break;
|
|
case 'warning':
|
|
$rank = 4;
|
|
break;
|
|
}
|
|
return $rank;
|
|
}
|
|
|
|
private function getWorstGlyphForFolder($treeFolder)
|
|
{
|
|
$worstStatus = 'unknown';
|
|
$worstStatusRank = -PHP_INT_MAX;
|
|
array_walk_recursive($treeFolder, function ($value) use (&$worstStatus, &$worstStatusRank)
|
|
{
|
|
$currentStatus = e_file_inspector::getStatusForValidationCode($value);
|
|
$currentStatusRank = $this->getStatusRank($currentStatus);
|
|
if ($currentStatusRank > $worstStatusRank)
|
|
{
|
|
$worstStatusRank = $currentStatusRank;
|
|
$worstStatus = $currentStatus;
|
|
}
|
|
});
|
|
return $this->glyph['folder_' . $worstStatus];
|
|
}
|
|
|
|
private function displayAllowed($validationCode)
|
|
{
|
|
if ($this->opt('core') == 'integrity_fail_only' &&
|
|
$validationCode & e_file_inspector::VALIDATED)
|
|
return false;
|
|
elseif ($this->opt('core') == 'none' &&
|
|
$validationCode & e_file_inspector::VALIDATED_PATH_VERSION)
|
|
return false;
|
|
|
|
$status = e_file_inspector::getStatusForValidationCode($validationCode);
|
|
$return = true;
|
|
switch ($status)
|
|
{
|
|
case 'missing':
|
|
$return = $this->opt('missing');
|
|
break;
|
|
case 'unknown':
|
|
$return = $this->opt('noncore');
|
|
break;
|
|
case 'old':
|
|
$return = $this->opt('oldcore');
|
|
break;
|
|
}
|
|
return $return;
|
|
}
|
|
|
|
/**
|
|
* Set an array item to a given value using "slash" notation.
|
|
*
|
|
* If no key is given to the method, the entire array will be replaced.
|
|
*
|
|
* Based on Illuminate\Support\Arr::set()
|
|
*
|
|
* @param array $array
|
|
* @param string|null $key
|
|
* @param mixed $value
|
|
* @return array
|
|
* @copyright Copyright (c) Taylor Otwell
|
|
* @license https://github.com/illuminate/support/blob/master/LICENSE.md MIT License
|
|
*/
|
|
private static function array_set(&$array, $key, $value)
|
|
{
|
|
if (is_null($key))
|
|
{
|
|
return $array = $value;
|
|
}
|
|
|
|
$keys = explode('/', $key);
|
|
|
|
while (count($keys) > 1)
|
|
{
|
|
$key = array_shift($keys);
|
|
|
|
// If the key doesn't exist at this depth, we will just create an empty array
|
|
// to hold the next value, allowing us to create the arrays to hold final
|
|
// values at the correct depth. Then we'll keep digging into the array.
|
|
if (!isset($array[$key]) || !is_array($array[$key]))
|
|
{
|
|
$array[$key] = [];
|
|
}
|
|
|
|
$array = &$array[$key];
|
|
}
|
|
|
|
$array[array_shift($keys)] = $value;
|
|
|
|
return $array;
|
|
}
|
|
|
|
|
|
function scan_results()
|
|
{
|
|
$this->count = [
|
|
'core' => [
|
|
'num' => 0,
|
|
'size' => 0,
|
|
],
|
|
'fail' => [
|
|
'num' => 0,
|
|
'size' => 0,
|
|
],
|
|
'pass' => [
|
|
'num' => 0,
|
|
'size' => 0,
|
|
],
|
|
'uncalculable' => [
|
|
'num' => 0,
|
|
'size' => 0,
|
|
],
|
|
'missing' => [
|
|
'num' => 0,
|
|
],
|
|
'deprecated' => [
|
|
'num' => 0,
|
|
'size' => 0,
|
|
],
|
|
'unknown' => [
|
|
'num' => 0,
|
|
'size' => 0,
|
|
],
|
|
'warning' => [
|
|
'num' => 0,
|
|
'size' => 0,
|
|
]
|
|
];
|
|
$this->inspect($this->root_dir);
|
|
|
|
array_walk_recursive($this->files, function ($validationCode)
|
|
{
|
|
$status = e_file_inspector::getStatusForValidationCode($validationCode);
|
|
$category = $this->statusToLegacyCountCategory($status);
|
|
$this->count[$category]['num']++;
|
|
if ($validationCode & e_file_inspector::VALIDATED_PATH_VERSION &&
|
|
$validationCode & e_file_inspector::VALIDATED_FILE_EXISTS)
|
|
$this->count['core']['num']++;
|
|
|
|
|
|
});
|
|
|
|
echo "<div style='display:block;height:30px'> </div>";
|
|
|
|
if($this->opt('type') == 'tree')
|
|
{
|
|
$text = "<div style='text-align:center'>
|
|
<table class='table table-bordered'>
|
|
<tr>
|
|
<th class='fcaption' colspan='2'>".FR_LAN_2."</th>
|
|
</tr>";
|
|
|
|
$text .= "<tr style='display: none'><td style='width:60%'></td><td style='width:40%'></td></tr>";
|
|
|
|
$text .= "<tr>
|
|
<td class='text-left' style='width:60%;padding:10px; '>
|
|
<div style=' min-height:400px; max-height:800px; overflow: auto; padding-bottom:50px'>
|
|
".$this->generateScanResultsHtml()."
|
|
</div>
|
|
</td>
|
|
<td style='width:40%; height:5000px; vertical-align: top; overflow:auto; padding:0'><div>";
|
|
}
|
|
else
|
|
{
|
|
$text = "<h3>".FR_LAN_2."</h3>";
|
|
}
|
|
|
|
$text .= "<table class='table-striped table table-bordered' id='initial'>";
|
|
|
|
if($this->opt('type') == 'tree')
|
|
{
|
|
$text .= "<tr><th class='text-left f' >".FR_LAN_3."</th>
|
|
<th class='s text-right' style='padding-right: 4px' onclick=\"sh('f_".dechex(crc32($this->root_dir))."')\">
|
|
<b class='caret'></b></th></tr>";
|
|
}
|
|
else
|
|
{
|
|
$text .= "<tr><th class='text-left f' colspan='2'>".FR_LAN_3."</th></tr>";
|
|
}
|
|
|
|
if($this->opt('core') != 'none')
|
|
{
|
|
$text .= "<tr><td class='text-left f'>".$this->iconTag['file_core']." ".FC_LAN_5.": ".($this->count['core']['num'] ? $this->count['core']['num'] : LAN_NONE)." </td>
|
|
<td class='s'>".$this->parsesize($this->count['core']['size'], 2)."</td></tr>";
|
|
}
|
|
if($this->opt('missing'))
|
|
{
|
|
$text .= "<tr><td class='text-left f' colspan='2'>".$this->iconTag['file_missing']." ".FC_LAN_13.": ".($this->count['missing']['num'] ? $this->count['missing']['num'] : LAN_NONE)." </td></tr>";
|
|
}
|
|
if($this->opt('noncore'))
|
|
{
|
|
$text .= "<tr><td class='text-left f'>".$this->iconTag['file_unknown']." ".FC_LAN_7.": ".($this->count['unknown']['num'] ? $this->count['unknown']['num'] : LAN_NONE)." </td><td class='s'>".$this->parsesize($this->count['unknown']['size'], 2)."</td></tr>";
|
|
}
|
|
if($this->opt('oldcore'))
|
|
{
|
|
$text .= "<tr><td class='text-left f'>".$this->iconTag['file_old']." ".FR_LAN_24.": ".($this->count['deprecated']['num'] ? $this->count['deprecated']['num'] : LAN_NONE)." </td><td class='s'>".$this->parsesize($this->count['deprecated']['size'], 2)."</td></tr>";
|
|
}
|
|
if($this->opt('core') == 'all')
|
|
{
|
|
$text .= "<tr><td class='text-left f'>".$this->iconTag['file']." ".FR_LAN_6.": ".($this->count['core']['num'] + $this->count['unknown']['num'] + $this->count['deprecated']['num'])." </td><td class='s'>".$this->parsesize($this->count['core']['size'] + $this->count['unknown']['size'] + $this->count['deprecated']['size'], 2)."</td></tr>";
|
|
}
|
|
|
|
if($this->count['warning']['num'])
|
|
{
|
|
$text .= "<tr><td colspan='2'> </td></tr>";
|
|
$text .= "<tr><td style='padding-left: 4px' colspan='2'>
|
|
".$this->iconTag['warning']." <b>".FR_LAN_26."</b></td></tr>";
|
|
|
|
$text .= "<tr><td class='text-left f'>".$this->iconTag['file_warning']." ".FR_LAN_28.": ".($this->count['warning']['num'] ? $this->count['warning']['num'] : LAN_NONE)." </td><td class='s'>".$this->parsesize($this->count['warning']['size'], 2)."</td></tr>";
|
|
|
|
$text .= "<tr><td class='w' colspan='2'><div class='alert alert-warning'>".FR_LAN_27."</div></td></tr>";
|
|
|
|
}
|
|
if($this->opt('integrity') && ($this->opt('core') != 'none'))
|
|
{
|
|
$integrity_icon = $this->count['fail']['num'] ? 'integrity_fail.png' : 'integrity_pass.png';
|
|
$integrity_text = $this->count['fail']['num'] ? '( '.$this->count['fail']['num'].' '.FR_LAN_19.' )' : '( '.FR_LAN_20.' )';
|
|
$text .= "<tr><td colspan='2'> </td></tr>";
|
|
$text .= "<tr><th class='text-left f' colspan='2'>".FR_LAN_7." ".$integrity_text."</th></tr>";
|
|
|
|
$text .= "<tr><td class='text-left f'>".$this->iconTag['file_check']." ".FR_LAN_8.": ".($this->count['pass']['num'] ? $this->count['pass']['num'] : LAN_NONE)." </td><td class='s'>".$this->parsesize($this->count['pass']['size'], 2)."</td></tr>";
|
|
$text .= "<tr><td class='text-left f'>".$this->iconTag['file_fail']." ".FR_LAN_9.": ".($this->count['fail']['num'] ? $this->count['fail']['num'] : LAN_NONE)." </td><td class='s'>".$this->parsesize($this->count['fail']['size'], 2)."</td></tr>";
|
|
$text .= "<tr><td class='text-left f'>".$this->iconTag['file_uncalc']." ".FR_LAN_25.": ".($this->count['uncalculable']['num'] ? $this->count['uncalculable']['num'] : LAN_NONE)." </td><td class='s'>".$this->parsesize($this->count['uncalculable']['size'], 2)."</td></tr>";
|
|
|
|
$text .= "<tr><td colspan='2'> </td></tr>";
|
|
|
|
$text .= "<tr><td class='text-left f' colspan='2'>".$this->iconTag['info']." ".FR_LAN_10.": </td></tr>";
|
|
|
|
$text .= "<tr><td class='text-left' style='padding-right: 4px' colspan='2'>
|
|
<ul><li>
|
|
<a href=\"#\" onclick=\"expandit('i_corrupt')\">".FR_LAN_11."...</a><div style='display: none' id='i_corrupt'>
|
|
".FR_LAN_12."<br /><br /></div>
|
|
</li><li>
|
|
<a href=\"#\" onclick=\"expandit('i_date')\">".FR_LAN_13."...</a><div style='display: none' id='i_date'>
|
|
".FR_LAN_14."<br /><br /></div>
|
|
</li><li>
|
|
<a href=\"#\" onclick=\"expandit('i_edit')\">".FR_LAN_15."...</a><div style='display: none' id='i_edit'>
|
|
".FR_LAN_16."<br /><br /></div>
|
|
</li><li>
|
|
<a href=\"#\" onclick=\"expandit('i_cvs')\">".FR_LAN_17."...</a><div style='display: none' id='i_cvs'>
|
|
".FR_LAN_18."<br /><br /></div>
|
|
</li></ul>
|
|
</td></tr>";
|
|
}
|
|
|
|
if($this->opt('type') == 'tree' && !$this->results && $this->opt('regex'))
|
|
{
|
|
$text .= "</td></tr>
|
|
<tr><td class='text-left' style='padding-right: 4px; text-align: center' colspan='2'><br />".FR_LAN_23."</td></tr>";
|
|
}
|
|
|
|
$text .= "</table>";
|
|
|
|
if($this->opt('type') != 'tree')
|
|
{
|
|
$text .= "
|
|
<table class='table table-striped table-bordered'>";
|
|
if(!$this->results && $this->opt('regex'))
|
|
{
|
|
$text .= "<tr><td class='text-left f' style='padding-left: 4px; text-align: center' colspan='2'>".FR_LAN_23."</td></tr>";
|
|
}
|
|
|
|
ksort($this->files);
|
|
foreach ($this->files as $relativePath => $validation)
|
|
{
|
|
if (!$this->displayAllowed($validation)) continue;
|
|
list($icon, $title) = $this->getGlyphForValidationCode($validation);
|
|
$text .= '<tr><td class="text-left f" title="'.$title.'">';
|
|
$text .= "$icon ";
|
|
$text .= htmlspecialchars($relativePath);
|
|
$text .= '</td><td class="s">';
|
|
$text .= isset($this->fileSizes[$relativePath]) ? $this->parsesize($this->fileSizes[$relativePath]) : '';
|
|
$oldVersion = $this->getOldVersionOfPath($relativePath, $validation);
|
|
$text .= $oldVersion ? " (v$oldVersion)" : "";
|
|
$text .= '</td>';
|
|
$text .= '</tr>';
|
|
}
|
|
}
|
|
|
|
$text .= "</td></tr>";
|
|
|
|
$text .= "</table>
|
|
</div><br />";
|
|
|
|
echo $text;
|
|
|
|
$this->sendProgress($this->totalFiles);
|
|
self::pruneOldProgressFiles();
|
|
}
|
|
|
|
function checksum($filename)
|
|
{
|
|
$checksum = md5(str_replace(array(chr(13),chr(10)), "", file_get_contents($filename)));
|
|
return $checksum;
|
|
}
|
|
|
|
function parsesize($size, $dec = 0) {
|
|
$size = $size ? $size : 0;
|
|
$kb = 1024;
|
|
$mb = 1024 * $kb;
|
|
$gb = 1024 * $mb;
|
|
$tb = 1024 * $gb;
|
|
if($size < $kb) {
|
|
return $size." ".CORE_LAN_B;
|
|
} elseif($size < $mb) {
|
|
return round($size/$kb)." ".CORE_LAN_KB;
|
|
} elseif($size < $gb) {
|
|
return round($size/$mb, $dec)." ".CORE_LAN_MB;
|
|
} elseif($size < $tb) {
|
|
return round($size/$gb, $dec)." ".CORE_LAN_GB;
|
|
} else {
|
|
return round($size/$tb, $dec)." ".CORE_LAN_TB;
|
|
}
|
|
}
|
|
|
|
function regex_match($file) {
|
|
$file_content = file_get_contents($file);
|
|
$match = preg_match($_POST['regex'], $file_content);
|
|
|
|
return $match;
|
|
}
|
|
|
|
|
|
function sendProgress($increment=0)
|
|
{
|
|
if(empty($this->options['scan']))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
$this->progress_units = $this->progress_units + $increment;
|
|
|
|
$rand = (int) $this->progress_units;
|
|
$total = (int) $this->totalFiles;
|
|
|
|
$inc = round(($rand / $total) * 100);
|
|
|
|
if($inc >= 100)
|
|
{
|
|
$inc = 100;
|
|
}
|
|
|
|
if( $this->progressPercentage === $inc)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
$this->progressPercentage = $inc;
|
|
|
|
self::writeScanProgress($this->options['scan'], $this->progressPercentage);
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
public function exploit_interface()
|
|
{
|
|
// global $ns;
|
|
$ns = e107::getRender();
|
|
|
|
$query = http_build_query($_POST);
|
|
|
|
$text = "
|
|
|
|
<iframe src='".e_SELF."?$query' width='96%' style='margin-left:0; width: 98%; height:100vh; min-height: 100000px; border: 0px' frameborder='0' scrolling='auto' ></iframe>
|
|
|
|
";
|
|
$ns->tablerender(FR_LAN_1, $text);
|
|
}
|
|
|
|
|
|
function headerCss()
|
|
{
|
|
$pref = e107::getPref();
|
|
|
|
echo "<!-- *CSS* -->\n";
|
|
$e_js = e107::getJs();
|
|
|
|
// Core CSS - XXX awaiting for path changes
|
|
if(!isset($no_core_css) || !$no_core_css)
|
|
{
|
|
//echo "<link rel='stylesheet' href='".e_FILE_ABS."e107.css' type='text/css' />\n";
|
|
$e_js->otherCSS('{e_WEB_CSS}e107.css');
|
|
}
|
|
|
|
|
|
if(!deftrue('e_IFRAME') && isset($pref['admincss']) && $pref['admincss'])
|
|
{
|
|
$css_file = file_exists(THEME.'admin_'.$pref['admincss']) ? 'admin_'.$pref['admincss'] : $pref['admincss'];
|
|
//echo "<link rel='stylesheet' href='".$css_file."' type='text/css' />\n";
|
|
$e_js->themeCSS($css_file);
|
|
}
|
|
elseif(isset($pref['themecss']) && $pref['themecss'])
|
|
{
|
|
$css_file = file_exists(THEME.'admin_'.$pref['themecss']) ? 'admin_'.$pref['themecss'] : $pref['themecss'];
|
|
//echo "<link rel='stylesheet' href='".$css_file."' type='text/css' />\n";
|
|
$e_js->themeCSS($css_file);
|
|
}
|
|
else
|
|
{
|
|
$css_file = file_exists(THEME.'admin_style.css') ? 'admin_style.css' : 'style.css';
|
|
//echo "<link rel='stylesheet' href='".$css_file."' type='text/css' />\n";
|
|
$e_js->themeCSS($css_file);
|
|
}
|
|
|
|
|
|
$e_js->renderJs('other_css', false, 'css', false);
|
|
echo "\n<!-- footer_other_css -->\n";
|
|
|
|
// Core CSS
|
|
$e_js->renderJs('core_css', false, 'css', false);
|
|
echo "\n<!-- footer_core_css -->\n";
|
|
|
|
// Plugin CSS
|
|
$e_js->renderJs('plugin_css', false, 'css', false);
|
|
echo "\n<!-- footer_plugin_css -->\n";
|
|
|
|
// Theme CSS
|
|
//echo "<!-- Theme css -->\n";
|
|
$e_js->renderJs('theme_css', false, 'css', false);
|
|
echo "\n<!-- footer_theme_css -->\n";
|
|
|
|
// Inline CSS - not sure if this should stay at all!
|
|
$e_js->renderJs('inline_css', false, 'css', false);
|
|
echo "\n<!-- footer_inline_css -->\n";
|
|
|
|
$text = "
|
|
<style type='text/css'>
|
|
<!--\n";
|
|
if (vartrue($_POST['regex']))
|
|
{
|
|
$text .= ".f { padding: 1px 0px 1px 8px; vertical-align: bottom; width: 90% }\n";
|
|
}
|
|
else
|
|
{
|
|
$text .= ".f { padding: 1px 0px 1px 8px; vertical-align: bottom; width: 90%; white-space: nowrap }\n";
|
|
}
|
|
$text .= ".d { margin: 2px 0px 1px 8px; cursor: default; white-space: nowrap }
|
|
.s { padding: 1px 8px 1px 0px; vertical-align: bottom; width: 10%; white-space: nowrap }
|
|
.t { margin-top: 1px; width: 100%; border-collapse: collapse; border-spacing: 0px }
|
|
.w { padding: 1px 0px 1px 8px; vertical-align: bottom; width: 90% }
|
|
.i { width: 16px; height: 16px }
|
|
.e { width: 9px; height: 9px }
|
|
i.fa-folder-open-o, i.fa-times-circle-o { cursor:pointer }
|
|
-->
|
|
</style>\n";
|
|
echo $text;
|
|
}
|
|
|
|
/**
|
|
* Get the PHP-standard version of the hash of the relative path
|
|
*
|
|
* @todo FIXME performance: This method checksums old files a second time.
|
|
* @param string $relativePath Relative path to checksum
|
|
* @param int $validationCode e_file_inspector validation bits
|
|
* @return false|string
|
|
*/
|
|
private function getOldVersionOfPath($relativePath, $validationCode)
|
|
{
|
|
$oldVersion = false;
|
|
if (($validationCode & e_file_inspector::VALIDATED_HASH_EXISTS) &&
|
|
!($validationCode & e_file_inspector::VALIDATED_HASH_CURRENT))
|
|
{
|
|
$dbChecksums = $this->coreImage->getChecksums($relativePath);
|
|
$actualChecksum = $this->coreImage->checksumPath(e_BASE . $relativePath);
|
|
$oldVersion = array_search($actualChecksum, $dbChecksums);
|
|
}
|
|
return $oldVersion;
|
|
}
|
|
|
|
private static function writeScanProgress($scanId, $progress)
|
|
{
|
|
self::exitOnEvilScanId($scanId);
|
|
$tmpDir = sys_get_temp_dir();
|
|
$progressPath = $tmpDir . "/" . self::SCAN_ID_PREFIX . $scanId;
|
|
if ($progress >= 100) unlink($progressPath);
|
|
else file_put_contents($progressPath, $progress);
|
|
}
|
|
|
|
public static function readScanProgress($scanId)
|
|
{
|
|
self::exitOnEvilScanId($scanId);
|
|
$tmpDir = sys_get_temp_dir();
|
|
$progressPath = $tmpDir . "/" . self::SCAN_ID_PREFIX . $scanId;
|
|
$result = trim(@file_get_contents($progressPath));
|
|
if (!strlen($result)) $result = '100';
|
|
return $result;
|
|
}
|
|
|
|
private static function exitOnEvilScanId($scanId)
|
|
{
|
|
if (!preg_match('/^[0-9A-F]+$/i', $scanId)) exit(1);
|
|
}
|
|
|
|
private static function pruneOldProgressFiles()
|
|
{
|
|
$tmpDir = sys_get_temp_dir();
|
|
$i = new DirectoryIterator($tmpDir);
|
|
foreach ($i as $fileInfo)
|
|
{
|
|
$candidateFileName = $fileInfo->getFilename();
|
|
if (substr($candidateFileName, 0, strlen(self::SCAN_ID_PREFIX)) !== self::SCAN_ID_PREFIX)
|
|
continue;
|
|
|
|
if ($fileInfo->isFile() && time() - $fileInfo->getMTime() > 300)
|
|
unlink($fileInfo->getRealPath());
|
|
}
|
|
}
|
|
}
|
|
/*
|
|
function fileinspector_adminmenu() //FIXME - has problems when navigation is on the LEFT instead of the right.
|
|
{
|
|
$var['setup']['text'] = FC_LAN_11;
|
|
$var['setup']['link'] = e_SELF."?mode=setup";
|
|
|
|
$var['run']['text'] = FR_LAN_2;
|
|
$var['run']['link'] = e_SELF."?mode=run";
|
|
|
|
$icon = e107::getParser()->toIcon('e-fileinspector-24');
|
|
$caption = $icon."<span>".FC_LAN_1."</span>";
|
|
|
|
e107::getNav()->admin($caption, $_GET['mode'], $var);
|
|
}*/
|
|
|
|
function e_help()
|
|
{
|
|
|
|
// $fi = new file_inspector;
|
|
$fi = e107::getSingleton('file_inspector');
|
|
$list = $fi->getLegend();
|
|
|
|
$text = '';
|
|
foreach($list as $v)
|
|
{
|
|
if(!empty($v[1]))
|
|
{
|
|
$text .= "<div>".$v[0]." ".$v[1]."</div>";
|
|
}
|
|
|
|
}
|
|
|
|
return array('caption'=>FC_LAN_37, 'text'=>$text);
|
|
|
|
}
|
|
|
|
|
|
require_once(e_ADMIN.'footer.php');
|
|
/*
|
|
function headerjs()
|
|
{
|
|
e107::js('footer', '{e_WEB}/js/core/all.jquery.js', 'jquery', 1);
|
|
e107::js('footer', '{e_WEB}js/core/front.jquery.js', 'jquery', 1); // Load all default functions.
|
|
|
|
$text = e107::getJs()->renderJs('footer', 1, true, true);
|
|
|
|
$text .= "<script type='text/javascript'>
|
|
<!--
|
|
c = new Image(); c = '".SITEURLBASE.e_IMAGE_ABS."fileinspector/contract.png';
|
|
e = '".SITEURLBASE.e_IMAGE_ABS."fileinspector/expand.png';
|
|
function ec(ecid) {
|
|
icon = document.getElementById('e_' + ecid).src;
|
|
if(icon.indexOf('expand.png') !== -1) {
|
|
document.getElementById('e_' + ecid).src = c;
|
|
} else {
|
|
document.getElementById('e_' + ecid).src = e;
|
|
}
|
|
div = document.getElementById('d_' + ecid).style;
|
|
if(div.display == 'none') {
|
|
div.display = '';
|
|
} else {
|
|
div.display = 'none';
|
|
}
|
|
}
|
|
var hideid = 'initial';
|
|
function sh(showid) {
|
|
if(hideid != showid) {
|
|
show = document.getElementById(showid).style;
|
|
hide = document.getElementById(hideid).style;
|
|
show.display = '';
|
|
hide.display = 'none';
|
|
hideid = showid;
|
|
}
|
|
}
|
|
//-->
|
|
</script>";
|
|
|
|
return $text;
|
|
}*/
|
|
|
|
?>
|