primo commit
This commit is contained in:
272
libraries/f0f/utils/filescheck/filescheck.php
Normal file
272
libraries/f0f/utils/filescheck/filescheck.php
Normal file
@ -0,0 +1,272 @@
|
||||
<?php
|
||||
/**
|
||||
* @package FrameworkOnFramework
|
||||
* @subpackage utils
|
||||
* @copyright Copyright (C) 2010-2016 Nicholas K. Dionysopoulos / Akeeba Ltd. All rights reserved.
|
||||
* @license GNU General Public License version 2 or later; see LICENSE.txt
|
||||
*/
|
||||
|
||||
defined('F0F_INCLUDED') or die;
|
||||
|
||||
/**
|
||||
* A utility class to check that your extension's files are not missing and have not been tampered with.
|
||||
*
|
||||
* You need a file called fileslist.php in your component's administrator root directory with the following contents:
|
||||
*
|
||||
* $phpFileChecker = array(
|
||||
* 'version' => 'revCEE2DAB',
|
||||
* 'date' => '2014-10-16',
|
||||
* 'directories' => array(
|
||||
* 'administrator/components/com_foobar',
|
||||
* ....
|
||||
* ),
|
||||
* 'files' => array(
|
||||
* 'administrator/components/com_foobar/access.xml' => array('705', '09aa0351a316bf011ecc8c1145134761', 'b95f00c7b49a07a60570dc674f2497c45c4e7152'),
|
||||
* ....
|
||||
* )
|
||||
* );
|
||||
*
|
||||
* All directory and file paths are relative to the site's root
|
||||
*
|
||||
* The directories array is a list of
|
||||
*/
|
||||
class F0FUtilsFilescheck
|
||||
{
|
||||
/** @var string The name of the component */
|
||||
protected $option = '';
|
||||
|
||||
/** @var string Current component version */
|
||||
protected $version = null;
|
||||
|
||||
/** @var string Current component release date */
|
||||
protected $date = null;
|
||||
|
||||
/** @var array List of files to check as filepath => (filesize, md5, sha1) */
|
||||
protected $fileList = array();
|
||||
|
||||
/** @var array List of directories to check that exist */
|
||||
protected $dirList = array();
|
||||
|
||||
/** @var bool Is the reported component version different than the version of the #__extensions table? */
|
||||
protected $wrongComponentVersion = false;
|
||||
|
||||
/** @var bool Is the fileslist.php reporting a version different than the reported component version? */
|
||||
protected $wrongFilesVersion = false;
|
||||
|
||||
/**
|
||||
* Create and initialise the object
|
||||
*
|
||||
* @param string $option Component name, e.g. com_foobar
|
||||
* @param string $version The current component version, as reported by the component
|
||||
* @param string $date The current component release date, as reported by the component
|
||||
*/
|
||||
public function __construct($option, $version, $date)
|
||||
{
|
||||
// Initialise from parameters
|
||||
$this->option = $option;
|
||||
$this->version = $version;
|
||||
$this->date = $date;
|
||||
|
||||
// Retrieve the date and version from the #__extensions table
|
||||
$db = F0FPlatform::getInstance()->getDbo();
|
||||
$query = $db->getQuery(true)->select('*')->from($db->qn('#__extensions'))
|
||||
->where($db->qn('element') . ' = ' . $db->q($this->option))
|
||||
->where($db->qn('type') . ' = ' . $db->q('component'));
|
||||
$extension = $db->setQuery($query)->loadObject();
|
||||
|
||||
// Check the version and date against those from #__extensions. I hate heavily nested IFs as much as the next
|
||||
// guy, but what can you do...
|
||||
if (!is_null($extension))
|
||||
{
|
||||
$manifestCache = $extension->manifest_cache;
|
||||
|
||||
if (!empty($manifestCache))
|
||||
{
|
||||
$manifestCache = json_decode($manifestCache, true);
|
||||
|
||||
if (is_array($manifestCache) && isset($manifestCache['creationDate']) && isset($manifestCache['version']))
|
||||
{
|
||||
// Make sure the fileslist.php version and date match the component's version
|
||||
if ($this->version != $manifestCache['version'])
|
||||
{
|
||||
$this->wrongComponentVersion = true;
|
||||
}
|
||||
|
||||
if ($this->date != $manifestCache['creationDate'])
|
||||
{
|
||||
$this->wrongComponentVersion = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Try to load the fileslist.php file from the component's back-end root
|
||||
$filePath = JPATH_ADMINISTRATOR . '/components/' . $this->option . '/fileslist.php';
|
||||
|
||||
if (!file_exists($filePath))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
include $filePath;
|
||||
|
||||
// Make sure the fileslist.php version and date match the component's version
|
||||
if ($this->version != $phpFileChecker['version'])
|
||||
{
|
||||
$this->wrongFilesVersion = true;
|
||||
}
|
||||
|
||||
if ($this->date != $phpFileChecker['date'])
|
||||
{
|
||||
$this->wrongFilesVersion = true;
|
||||
}
|
||||
|
||||
// Initialise the files and directories lists
|
||||
$this->fileList = $phpFileChecker['files'];
|
||||
$this->dirList = $phpFileChecker['directories'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the reported component version different than the version of the #__extensions table?
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isWrongComponentVersion()
|
||||
{
|
||||
return $this->wrongComponentVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the fileslist.php reporting a version different than the reported component version?
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function isWrongFilesVersion()
|
||||
{
|
||||
return $this->wrongFilesVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a fast check of file and folders. If even one of the files/folders doesn't exist, or even one file has
|
||||
* the wrong file size it will return false.
|
||||
*
|
||||
* @return bool False when there are mismatched files and directories
|
||||
*/
|
||||
public function fastCheck()
|
||||
{
|
||||
// Check that all directories exist
|
||||
foreach ($this->dirList as $directory)
|
||||
{
|
||||
$directory = JPATH_ROOT . '/' . $directory;
|
||||
|
||||
if (!@is_dir($directory))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check that all files exist and have the right size
|
||||
foreach ($this->fileList as $filePath => $fileData)
|
||||
{
|
||||
$filePath = JPATH_ROOT . '/' . $filePath;
|
||||
|
||||
if (!@file_exists($filePath))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$fileSize = @filesize($filePath);
|
||||
|
||||
if ($fileSize != $fileData[0])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a slow, thorough check of all files and folders (including MD5/SHA1 sum checks)
|
||||
*
|
||||
* @param int $idx The index from where to start
|
||||
*
|
||||
* @return array Progress report
|
||||
*/
|
||||
public function slowCheck($idx = 0)
|
||||
{
|
||||
$ret = array(
|
||||
'done' => false,
|
||||
'files' => array(),
|
||||
'folders' => array(),
|
||||
'idx' => $idx
|
||||
);
|
||||
|
||||
$totalFiles = count($this->fileList);
|
||||
$totalFolders = count($this->dirList);
|
||||
$fileKeys = array_keys($this->fileList);
|
||||
|
||||
$timer = new F0FUtilsTimer(3.0, 75.0);
|
||||
|
||||
while ($timer->getTimeLeft() && (($idx < $totalFiles) || ($idx < $totalFolders)))
|
||||
{
|
||||
if ($idx < $totalFolders)
|
||||
{
|
||||
$directory = JPATH_ROOT . '/' . $this->dirList[$idx];
|
||||
|
||||
if (!@is_dir($directory))
|
||||
{
|
||||
$ret['folders'][] = $directory;
|
||||
}
|
||||
}
|
||||
|
||||
if ($idx < $totalFiles)
|
||||
{
|
||||
$fileKey = $fileKeys[$idx];
|
||||
$filePath = JPATH_ROOT . '/' . $fileKey;
|
||||
$fileData = $this->fileList[$fileKey];
|
||||
|
||||
if (!@file_exists($filePath))
|
||||
{
|
||||
$ret['files'][] = $fileKey . ' (missing)';
|
||||
}
|
||||
elseif (@filesize($filePath) != $fileData[0])
|
||||
{
|
||||
$ret['files'][] = $fileKey . ' (size ' . @filesize($filePath) . ' ≠ ' . $fileData[0] . ')';
|
||||
}
|
||||
else
|
||||
{
|
||||
if (function_exists('sha1_file'))
|
||||
{
|
||||
$fileSha1 = @sha1_file($filePath);
|
||||
|
||||
if ($fileSha1 != $fileData[2])
|
||||
{
|
||||
$ret['files'][] = $fileKey . ' (SHA1 ' . $fileSha1 . ' ≠ ' . $fileData[2] . ')';
|
||||
}
|
||||
}
|
||||
elseif (function_exists('md5_file'))
|
||||
{
|
||||
$fileMd5 = @md5_file($filePath);
|
||||
|
||||
if ($fileMd5 != $fileData[1])
|
||||
{
|
||||
$ret['files'][] = $fileKey . ' (MD5 ' . $fileMd5 . ' ≠ ' . $fileData[1] . ')';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$idx++;
|
||||
}
|
||||
|
||||
if (($idx >= $totalFiles) && ($idx >= $totalFolders))
|
||||
{
|
||||
$ret['done'] = true;
|
||||
}
|
||||
|
||||
$ret['idx'] = $idx;
|
||||
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user