diff --git a/administrator/components/com_patchtester/PatchTester/Controller/ResetController.php b/administrator/components/com_patchtester/PatchTester/Controller/ResetController.php new file mode 100644 index 0000000..889d417 --- /dev/null +++ b/administrator/components/com_patchtester/PatchTester/Controller/ResetController.php @@ -0,0 +1,135 @@ +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)); + } +} diff --git a/administrator/components/com_patchtester/PatchTester/Controller/StartfetchController.php b/administrator/components/com_patchtester/PatchTester/Controller/StartfetchController.php index e85c272..79bb7af 100644 --- a/administrator/components/com_patchtester/PatchTester/Controller/StartfetchController.php +++ b/administrator/components/com_patchtester/PatchTester/Controller/StartfetchController.php @@ -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)); diff --git a/administrator/components/com_patchtester/PatchTester/Model/PullsModel.php b/administrator/components/com_patchtester/PatchTester/Model/PullsModel.php index 64599bb..afcf537 100644 --- a/administrator/components/com_patchtester/PatchTester/Model/PullsModel.php +++ b/administrator/components/com_patchtester/PatchTester/Model/PullsModel.php @@ -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. * diff --git a/administrator/components/com_patchtester/PatchTester/Model/TestsModel.php b/administrator/components/com_patchtester/PatchTester/Model/TestsModel.php new file mode 100644 index 0000000..08e6df7 --- /dev/null +++ b/administrator/components/com_patchtester/PatchTester/Model/TestsModel.php @@ -0,0 +1,54 @@ +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'); + } +} diff --git a/administrator/components/com_patchtester/PatchTester/View/Pulls/PullsHtmlView.php b/administrator/components/com_patchtester/PatchTester/View/Pulls/PullsHtmlView.php index 92ddaac..6166a66 100644 --- a/administrator/components/com_patchtester/PatchTester/View/Pulls/PullsHtmlView.php +++ b/administrator/components/com_patchtester/PatchTester/View/Pulls/PullsHtmlView.php @@ -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'); diff --git a/administrator/components/com_patchtester/language/en-GB/en-GB.com_patchtester.ini b/administrator/components/com_patchtester/language/en-GB/en-GB.com_patchtester.ini index e6ea849..98ec705 100644 --- a/administrator/components/com_patchtester/language/en-GB/en-GB.com_patchtester.ini +++ b/administrator/components/com_patchtester/language/en-GB/en-GB.com_patchtester.ini @@ -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" diff --git a/media/com_patchtester/js/patchtester.js b/media/com_patchtester/js/patchtester.js index d1f9057..333470e 100644 --- a/media/com_patchtester/js/patchtester.js +++ b/media/com_patchtester/js/patchtester.js @@ -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);