Add routine to reset the component's state (Fix #124)

This commit is contained in:
Michael Babker 2016-03-26 18:08:01 -04:00
parent bef895038f
commit 2af80cf8d4
7 changed files with 224 additions and 27 deletions

View File

@ -0,0 +1,135 @@
<?php
/**
* Patch testing component for the Joomla! CMS
*
* @copyright Copyright (C) 2011 - 2012 Ian MacLennan, Copyright (C) 2013 - 2016 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later
*/
namespace PatchTester\Controller;
use PatchTester\Model\PullModel;
use PatchTester\Model\PullsModel;
use PatchTester\Model\TestsModel;
/**
* Controller class to reset the system state
*
* @since 2.0
*/
class ResetController extends AbstractController
{
/**
* Execute the controller.
*
* @return void Redirects the application
*
* @since 2.0
*/
public function execute()
{
try
{
$hasErrors = false;
$pullModel = new PullModel(null, \JFactory::getDbo());
$pullsModel = new PullsModel($this->context, null, \JFactory::getDbo());
$testsModel = new TestsModel(null, \JFactory::getDbo());
// Check the applied patches in the database first
$appliedPatches = $testsModel->getAppliedPatches();
if (count($appliedPatches))
{
$revertErrored = false;
// Let's try to cleanly revert all applied patches
foreach ($appliedPatches as $patch)
{
try
{
$pullModel->revert($patch->id);
}
catch (\RuntimeException $e)
{
$revertErrored = true;
}
}
// If we errored out reverting patches, we'll need to truncate the table
if ($revertErrored)
{
try
{
$testsModel->truncateTable();
}
catch (\RuntimeException $e)
{
$hasErrors = true;
$this->getApplication()->enqueueMessage(
\JText::sprintf('COM_PATCHTESTER_ERROR_TRUNCATING_PULLS_TABLE', $e->getMessage()), 'error'
);
}
}
}
// Now truncate the pulls table
try
{
$pullsModel->truncateTable();
}
catch (\RuntimeException $e)
{
$hasErrors = true;
$this->getApplication()->enqueueMessage(
\JText::sprintf('COM_PATCHTESTER_ERROR_TRUNCATING_TESTS_TABLE', $e->getMessage()), 'error'
);
}
jimport('joomla.filesystem.file');
jimport('joomla.filesystem.folder');
// Check the backups directory to see if any .txt files remain; clear them if so
$backups = \JFolder::files(JPATH_COMPONENT . '/backups', '.txt');
if (count($backups))
{
foreach ($backups as $file)
{
if (!\JFile::delete(JPATH_COMPONENT . '/backups/' . $file))
{
$this->getApplication()->enqueueMessage(
\JText::sprintf('COM_PATCHTESTER_ERROR_CANNOT_DELETE_FILE', JPATH_COMPONENT . '/backups/' . $file), 'error'
);
$hasErrors = true;
}
}
}
// Processing completed, inform the user of a success or fail
if ($hasErrors)
{
$msg = \JText::sprintf(
'COM_PATCHTESTER_RESET_HAS_ERRORS', JPATH_COMPONENT . '/backups', \JFactory::getDbo()->replacePrefix('#__patchtester_tests')
);
$type = 'warning';
}
else
{
$msg = \JText::_('COM_PATCHTESTER_RESET_OK');
$type = 'info';
}
}
catch (\Exception $e)
{
$msg = $e->getMessage();
$type = 'error';
}
$this->getApplication()->enqueueMessage($msg, $type);
$this->getApplication()->redirect(\JRoute::_('index.php?option=com_patchtester', false));
}
}

View File

@ -10,6 +10,7 @@ namespace PatchTester\Controller;
use PatchTester\Helper;
use PatchTester\Model\PullsModel;
use PatchTester\Model\TestsModel;
/**
* Controller class to start fetching remote data
@ -84,15 +85,12 @@ class StartfetchController extends AbstractController
$this->getApplication()->close(1);
}
$model = new PullsModel('com_patchtester.fetch', null, \JFactory::getDbo());
// Initialize the state for the model
$model->setState($this->initializeState($model));
$testsModel = new TestsModel(null, \JFactory::getDbo());
try
{
// Sanity check, ensure there aren't any applied patches
if (count($model->getAppliedPatches()) >= 1)
if (count($testsModel->getAppliedPatches()) >= 1)
{
$response = new \JResponseJson(new \Exception(\JText::_('COM_PATCHTESTER_ERROR_APPLIED_PATCHES'), 500));

View File

@ -51,27 +51,6 @@ class PullsModel extends \JModelDatabase
$this->context = $context;
}
/**
* Retrieves a list of applied patches
*
* @return mixed
*
* @since 1.0
*/
public function getAppliedPatches()
{
$db = $this->getDb();
$db->setQuery(
$db->getQuery(true)
->select('*')
->from($db->quoteName('#__patchtester_tests'))
->where($db->quoteName('applied') . ' = 1')
);
return $db->loadObjectList('pull_id');
}
/**
* Method to get an array of data items.
*
@ -358,6 +337,18 @@ class PullsModel extends \JModelDatabase
return array('complete' => false, 'page' => ($page + 1));
}
/**
* Truncates the pulls table
*
* @return void
*
* @since 2.0
*/
public function truncateTable()
{
$this->getDb()->truncateTable('#__patchtester_pulls');
}
/**
* Gets an array of objects from the results of database query.
*

View File

@ -0,0 +1,54 @@
<?php
/**
* Patch testing component for the Joomla! CMS
*
* @copyright Copyright (C) 2011 - 2012 Ian MacLennan, Copyright (C) 2013 - 2016 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later
*/
namespace PatchTester\Model;
use Joomla\Registry\Registry;
use PatchTester\Helper;
/**
* Methods supporting applied pull requests.
*
* @since 2.0
*/
class TestsModel extends \JModelDatabase
{
/**
* Retrieves a list of applied patches
*
* @return mixed
*
* @since 2.0
*/
public function getAppliedPatches()
{
$db = $this->getDb();
$db->setQuery(
$db->getQuery(true)
->select('*')
->from($db->quoteName('#__patchtester_tests'))
->where($db->quoteName('applied') . ' = 1')
);
return $db->loadObjectList('pull_id');
}
/**
* Truncates the tests table
*
* @return void
*
* @since 2.0
*/
public function truncateTable()
{
$this->getDb()->truncateTable('#__patchtester_tests');
}
}

View File

@ -90,6 +90,9 @@ class PullsHtmlView extends DefaultHtmlView
$this->addToolbar();
// Make text strings available in the JavaScript API
\JText::script('COM_PATCHTESTER_CONFIRM_RESET');
return parent::render();
}
@ -106,7 +109,9 @@ class PullsHtmlView extends DefaultHtmlView
if (!count($this->envErrors))
{
\JToolbar::getInstance('toolbar')->appendButton(
$toolbar = \JToolbar::getInstance('toolbar');
$toolbar->appendButton(
'Popup',
'refresh',
'COM_PATCHTESTER_TOOLBAR_FETCH_DATA',
@ -118,6 +123,9 @@ class PullsHtmlView extends DefaultHtmlView
'window.parent.location.reload()',
'COM_PATCHTESTER_HEADING_FETCH_DATA'
);
// Add a reset button.
$toolbar->appendButton('Standard', 'expired', 'COM_PATCHTESTER_TOOLBAR_RESET', 'reset', false);
}
\JToolbarHelper::preferences('com_patchtester');

View File

@ -12,6 +12,7 @@ COM_PATCHTESTER_APPLY_PATCH="Apply Patch"
COM_PATCHTESTER_COMPONENT_DESC="Joomla! Patch Tester Configuration Values"
COM_PATCHTESTER_COMPONENT_LABEL="Joomla! Patch Tester"
COM_PATCHTESTER_CONFIGURATION="Joomla! Patch Tester Settings"
COM_PATCHTESTER_CONFIRM_RESET="Resetting will attempt to revert all applied patches and removes all backed up files. This may result in a corrupted environment. Are you sure you want to continue?"
COM_PATCHTESTER_CONFLICT_S="The patch could not be applied because it conflicts with a previously applied patch: %s"
COM_PATCHTESTER_COULD_NOT_CONNECT_TO_GITHUB="Could not connect to GitHub: %s"
COM_PATCHTESTER_DIFFERENT_SHA="The patch you've applied is in a different state than when data was last pulled from GitHub. Commit %1$s was expected however commit %2$s was applied."
@ -22,6 +23,8 @@ COM_PATCHTESTER_ERROR_CANNOT_WRITE_FILE="Cannot write file %s"
COM_PATCHTESTER_ERROR_GITHUB_FETCH="Error retrieving pull requests from GitHub: %s"
COM_PATCHTESTER_ERROR_INSERT_DATABASE="Error inserting pull request data into the database: %s"
COM_PATCHTESTER_ERROR_READING_DATABASE_TABLE="%1$s - Error retrieving table data (%2$s)"
COM_PATCHTESTER_ERROR_TRUNCATING_PULLS_TABLE="Error truncating the pulls table: %s"
COM_PATCHTESTER_ERROR_TRUNCATING_TESTS_TABLE="Error truncating the tests table: %s"
COM_PATCHTESTER_FETCH_AN_ERROR_HAS_OCCURRED="An error has occurred while fetching the data from GitHub."
COM_PATCHTESTER_FETCH_COMPLETE_CLOSE_WINDOW="All data has been retrieved. Please close this modal window to refresh the page."
COM_PATCHTESTER_FETCH_INITIALIZING="Preparing to fetch GitHub data"
@ -57,8 +60,11 @@ COM_PATCHTESTER_REQUIREMENT_HTTPS="HTTPS wrappers must be enabled"
COM_PATCHTESTER_REQUIREMENT_OPENSSL="The OpenSSL extension must be installed and enabled in your php.ini"
COM_PATCHTESTER_REQUIREMENTS_HEADING="Requirements Not Met"
COM_PATCHTESTER_REQUIREMENTS_NOT_MET="Your system does not meet the requirements to run the Patch Tester extension:"
COM_PATCHTESTER_RESET_HAS_ERRORS="The reset process has completed however it encountered errors. Please remove any .txt files in the '%1$s' directory and truncate the '%2$s' database table."
COM_PATCHTESTER_RESET_OK="The reset process has completed successfully."
COM_PATCHTESTER_REVERT_OK="Patch successfully reverted"
COM_PATCHTESTER_REVERT_PATCH="Revert Patch"
COM_PATCHTESTER_TEST_THIS_PATCH="Test This Patch"
COM_PATCHTESTER_TOOLBAR_FETCH_DATA="Fetch Data"
COM_PATCHTESTER_TOOLBAR_RESET="Reset"
COM_PATCHTESTER_SHA="SHA"

View File

@ -45,4 +45,9 @@ if (typeof Joomla === 'undefined') {
}
};
Joomla.submitbutton = function (task) {
if (task != 'reset' || confirm(Joomla.JText._('COM_PATCHTESTER_CONFIRM_RESET'))) {
Joomla.submitform(task);
}
};
}(Joomla, window, document);