mirror of
https://github.com/joomla-extensions/patchtester.git
synced 2025-01-23 15:18:36 +00:00
Refactor to be namespaced and not use legacy MVC
This commit is contained in:
parent
881d5fa9ae
commit
9171c4b234
@ -0,0 +1,46 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Patch testing component for the Joomla! CMS
|
||||||
|
*
|
||||||
|
* @copyright Copyright (C) 2011 - 2012 Ian MacLennan, Copyright (C) 2013 - 2014 Open Source Matters, Inc. All rights reserved.
|
||||||
|
* @license GNU General Public License version 2 or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace PatchTester\Controller;
|
||||||
|
|
||||||
|
use PatchTester\Model\PullModel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controller class to apply patches
|
||||||
|
*
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
class ApplyController extends \JControllerBase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Execute the controller.
|
||||||
|
*
|
||||||
|
* @return void Redirects the application
|
||||||
|
*
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public function execute()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$model = new PullModel;
|
||||||
|
$model->apply($this->getInput()->getUint('pull_id'));
|
||||||
|
|
||||||
|
$msg = \JText::_('COM_PATCHTESTER_APPLY_OK');
|
||||||
|
$type = 'message';
|
||||||
|
}
|
||||||
|
catch (\Exception $e)
|
||||||
|
{
|
||||||
|
$msg = $e->getMessage();
|
||||||
|
$type = 'error';
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->getApplication()->enqueueMessage($msg, $type);
|
||||||
|
$this->getApplication()->redirect(\JRoute::_('index.php?option=com_patchtester', false));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,179 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Patch testing component for the Joomla! CMS
|
||||||
|
*
|
||||||
|
* @copyright Copyright (C) 2011 - 2012 Ian MacLennan, Copyright (C) 2013 - 2014 Open Source Matters, Inc. All rights reserved.
|
||||||
|
* @license GNU General Public License version 2 or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace PatchTester\Controller;
|
||||||
|
|
||||||
|
use Joomla\Registry\Registry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default display controller
|
||||||
|
*
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
class DisplayController extends \JControllerBase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The object context
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
protected $context;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default ordering column
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
protected $defaultOrderColumn = 'a.pull_id';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default sort direction
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
protected $defaultDirection = 'DESC';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default view to display
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
protected $defaultView = 'pulls';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiate the controller
|
||||||
|
*
|
||||||
|
* @param \JInput $input The input object.
|
||||||
|
* @param \JApplicationBase $app The application object.
|
||||||
|
*
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public function __construct(\JInput $input = null, \JApplicationBase $app = null)
|
||||||
|
{
|
||||||
|
parent::__construct($input, $app);
|
||||||
|
|
||||||
|
// Set the context for the controller
|
||||||
|
$this->context = \JApplicationHelper::getComponentName() . '.' . $this->getInput()->getCmd('view', $this->defaultView);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the controller.
|
||||||
|
*
|
||||||
|
* @return boolean True on success
|
||||||
|
*
|
||||||
|
* @since 2.0
|
||||||
|
* @throws \RuntimeException
|
||||||
|
*/
|
||||||
|
public function execute()
|
||||||
|
{
|
||||||
|
// Set up variables to build our classes
|
||||||
|
$view = $this->getInput()->getCmd('view', $this->defaultView);
|
||||||
|
$format = $this->getInput()->getCmd('format', 'html');
|
||||||
|
|
||||||
|
// Register the layout paths for the view
|
||||||
|
$paths = new \SplPriorityQueue;
|
||||||
|
|
||||||
|
// Add the path for template overrides
|
||||||
|
$paths->insert(JPATH_THEMES . '/' . $this->getApplication()->getTemplate() . '/html/' . \JApplicationHelper::getComponentName() . '/' . $view, 2);
|
||||||
|
|
||||||
|
// Add the path for the default layouts
|
||||||
|
$paths->insert(JPATH_BASE . '/components/' . \JApplicationHelper::getComponentName() . '/PatchTester/View/' . $view . '/tmpl', 1);
|
||||||
|
|
||||||
|
// Build the class names for the model and view
|
||||||
|
$viewClass = '\\PatchTester\\View\\' . ucfirst($view) . '\\' . ucfirst($view) . ucfirst($format) . 'View';
|
||||||
|
$modelClass = '\\PatchTester\\Model\\' . ucfirst($view) . 'Model';
|
||||||
|
|
||||||
|
// Sanity check - Ensure our classes exist
|
||||||
|
if (!class_exists($viewClass))
|
||||||
|
{
|
||||||
|
throw new \RuntimeException(sprintf('The view class for the %1%s view in the %2%s was not found.', $view, $format), 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!class_exists($modelClass))
|
||||||
|
{
|
||||||
|
throw new \RuntimeException(sprintf('The model class for the %s view was not found.', $view), 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize the model class now; need to do it before setting the state to get required data from it
|
||||||
|
$model = new $modelClass($this->context, null, \JFactory::getDbo());
|
||||||
|
|
||||||
|
// Initialize the state for the model
|
||||||
|
$model->setState($this->initializeState($model));
|
||||||
|
|
||||||
|
// Initialize the view class now
|
||||||
|
$view = new $viewClass($model, $paths);
|
||||||
|
|
||||||
|
// Echo the rendered view for the application
|
||||||
|
echo $view->render();
|
||||||
|
|
||||||
|
// Finished!
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the state for the model object
|
||||||
|
*
|
||||||
|
* @param \JModel $model Model object
|
||||||
|
*
|
||||||
|
* @return Registry
|
||||||
|
*
|
||||||
|
* @since 2.0
|
||||||
|
* @todo This should really be more generic for a default controller
|
||||||
|
*/
|
||||||
|
protected function initializeState(\JModel $model)
|
||||||
|
{
|
||||||
|
$state = new Registry;
|
||||||
|
|
||||||
|
// Load the filter state.
|
||||||
|
$search = $this->getApplication()->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '');
|
||||||
|
$state->set('filter.search', $search);
|
||||||
|
|
||||||
|
// Load the parameters.
|
||||||
|
$params = \JComponentHelper::getParams('com_patchtester');
|
||||||
|
|
||||||
|
$state->set('params', $params);
|
||||||
|
$state->set('github_user', $params->get('org', 'joomla'));
|
||||||
|
$state->set('github_repo', $params->get('repo', 'joomla-cms'));
|
||||||
|
|
||||||
|
// Pre-fill the limits
|
||||||
|
$limit = $this->getApplication()->getUserStateFromRequest('global.list.limit', 'limit', $this->getApplication()->get('list_limit'), 'uint');
|
||||||
|
$state->set('list.limit', $limit);
|
||||||
|
|
||||||
|
// Check if the ordering field is in the white list, otherwise use the incoming value.
|
||||||
|
$value = $this->getApplication()->getUserStateFromRequest($this->context . '.ordercol', 'filter_order', $this->defaultOrderColumn);
|
||||||
|
|
||||||
|
if (!in_array($value, $model->getSortFields()))
|
||||||
|
{
|
||||||
|
$value = $this->defaultOrderColumn;
|
||||||
|
$this->getApplication()->setUserState($this->context . '.ordercol', $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
$state->set('list.ordering', $value);
|
||||||
|
|
||||||
|
// Check if the ordering direction is valid, otherwise use the incoming value.
|
||||||
|
$value = $this->getApplication()->getUserStateFromRequest($this->context . '.orderdirn', 'filter_order_Dir', $this->defaultDirection);
|
||||||
|
|
||||||
|
if (!in_array(strtoupper($value), array('ASC', 'DESC', '')))
|
||||||
|
{
|
||||||
|
$value = $this->defaultDirection;
|
||||||
|
$this->getApplication()->setUserState($this->context . '.orderdirn', $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
$state->set('list.direction', $value);
|
||||||
|
|
||||||
|
$value = $this->getApplication()->getUserStateFromRequest($this->context . '.limitstart', 'limitstart', 0);
|
||||||
|
$limitstart = ($limit != 0 ? (floor($value / $limit) * $limit) : 0);
|
||||||
|
$state->set('list.start', $limitstart);
|
||||||
|
|
||||||
|
return $state;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Patch testing component for the Joomla! CMS
|
||||||
|
*
|
||||||
|
* @copyright Copyright (C) 2011 - 2012 Ian MacLennan, Copyright (C) 2013 - 2014 Open Source Matters, Inc. All rights reserved.
|
||||||
|
* @license GNU General Public License version 2 or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace PatchTester\Controller;
|
||||||
|
|
||||||
|
use PatchTester\Model\PullsModel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controller class to fetch remote data
|
||||||
|
*
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
class FetchController extends \JControllerBase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Execute the controller.
|
||||||
|
*
|
||||||
|
* @return void Redirects the application
|
||||||
|
*
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public function execute()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// TODO - Decouple the model and context?
|
||||||
|
$model = new PullsModel('com_patchtester.fetch', null, \JFactory::getDbo());
|
||||||
|
$model->requestFromGithub();
|
||||||
|
|
||||||
|
$msg = \JText::_('COM_PATCHTESTER_FETCH_SUCCESSFUL');
|
||||||
|
$type = 'message';
|
||||||
|
}
|
||||||
|
catch (\Exception $e)
|
||||||
|
{
|
||||||
|
$msg = $e->getMessage();
|
||||||
|
$type = 'error';
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->getApplication()->enqueueMessage($msg, $type);
|
||||||
|
$this->getApplication()->redirect(\JRoute::_('index.php?option=com_patchtester', false));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Patch testing component for the Joomla! CMS
|
||||||
|
*
|
||||||
|
* @copyright Copyright (C) 2011 - 2012 Ian MacLennan, Copyright (C) 2013 - 2014 Open Source Matters, Inc. All rights reserved.
|
||||||
|
* @license GNU General Public License version 2 or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace PatchTester\Controller;
|
||||||
|
|
||||||
|
use PatchTester\Model\PullModel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controller class to revert patches
|
||||||
|
*
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
class RevertController extends \JControllerBase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Execute the controller.
|
||||||
|
*
|
||||||
|
* @return void Redirects the application
|
||||||
|
*
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public function execute()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$model = new PullModel;
|
||||||
|
$model->revert($this->getInput()->getUint('pull_id'));
|
||||||
|
|
||||||
|
$msg = \JText::_('COM_PATCHTESTER_APPLY_OK');
|
||||||
|
$type = 'message';
|
||||||
|
}
|
||||||
|
catch (\Exception $e)
|
||||||
|
{
|
||||||
|
$msg = $e->getMessage();
|
||||||
|
$type = 'error';
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->getApplication()->enqueueMessage($msg, $type);
|
||||||
|
$this->getApplication()->redirect(\JRoute::_('index.php?option=com_patchtester', false));
|
||||||
|
}
|
||||||
|
}
|
@ -1,33 +1,32 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* @package PatchTester
|
* Patch testing component for the Joomla! CMS
|
||||||
*
|
*
|
||||||
* @copyright Copyright (C) 2011 - 2012 Ian MacLennan, Copyright (C) 2013 - 2014 Open Source Matters, Inc. All rights reserved.
|
* @copyright Copyright (C) 2011 - 2012 Ian MacLennan, Copyright (C) 2013 - 2014 Open Source Matters, Inc. All rights reserved.
|
||||||
* @license GNU General Public License version 2 or later
|
* @license GNU General Public License version 2 or later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
defined('_JEXEC') or die;
|
namespace PatchTester;
|
||||||
|
|
||||||
use Joomla\Registry\Registry;
|
use Joomla\Registry\Registry;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper class for the patch tester component
|
* Helper class for the patch tester component
|
||||||
*
|
*
|
||||||
* @package PatchTester
|
* @since 2.0
|
||||||
* @since 2.0
|
|
||||||
*/
|
*/
|
||||||
abstract class PatchtesterHelper
|
abstract class Helper
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Initializes the JGithub object
|
* Initializes the JGithub object
|
||||||
*
|
*
|
||||||
* @return JGithub
|
* @return \JGithub
|
||||||
*
|
*
|
||||||
* @since 2.0
|
* @since 2.0
|
||||||
*/
|
*/
|
||||||
public static function initializeGithub()
|
public static function initializeGithub()
|
||||||
{
|
{
|
||||||
$params = JComponentHelper::getParams('com_patchtester');
|
$params = \JComponentHelper::getParams('com_patchtester');
|
||||||
|
|
||||||
$options = new Registry;
|
$options = new Registry;
|
||||||
|
|
||||||
@ -45,9 +44,9 @@ abstract class PatchtesterHelper
|
|||||||
// Display a message about the lowered API limit without credentials
|
// Display a message about the lowered API limit without credentials
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
JFactory::getApplication()->enqueueMessage(JText::_('COM_PATCHTESTER_NO_CREDENTIALS'), 'notice');
|
\JFactory::getApplication()->enqueueMessage(\JText::_('COM_PATCHTESTER_NO_CREDENTIALS'), 'notice');
|
||||||
}
|
}
|
||||||
|
|
||||||
return new JGithub($options);
|
return new \JGithub($options);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,22 +1,23 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* @package PatchTester
|
* Patch testing component for the Joomla! CMS
|
||||||
*
|
*
|
||||||
* @copyright Copyright (C) 2011 - 2012 Ian MacLennan, Copyright (C) 2013 - 2014 Open Source Matters, Inc. All rights reserved.
|
* @copyright Copyright (C) 2011 - 2012 Ian MacLennan, Copyright (C) 2013 - 2014 Open Source Matters, Inc. All rights reserved.
|
||||||
* @license GNU General Public License version 2 or later
|
* @license GNU General Public License version 2 or later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
defined('_JEXEC') or die;
|
namespace PatchTester\Model;
|
||||||
|
|
||||||
use Joomla\Registry\Registry;
|
use Joomla\Registry\Registry;
|
||||||
|
|
||||||
|
use PatchTester\Helper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Methods supporting pull requests.
|
* Methods supporting pull requests.
|
||||||
*
|
*
|
||||||
* @package PatchTester
|
* @since 2.0
|
||||||
* @since 1.0
|
|
||||||
*/
|
*/
|
||||||
class PatchtesterModelPull extends JModelLegacy
|
class PullModel extends \JModelBase
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Array containing top level non-production folders
|
* Array containing top level non-production folders
|
||||||
@ -32,7 +33,7 @@ class PatchtesterModelPull extends JModelLegacy
|
|||||||
* @return void
|
* @return void
|
||||||
*
|
*
|
||||||
* @note Calling getState() in this method will result in recursion.
|
* @note Calling getState() in this method will result in recursion.
|
||||||
* @since 1.0
|
* @since 2.0
|
||||||
*/
|
*/
|
||||||
protected function populateState()
|
protected function populateState()
|
||||||
{
|
{
|
||||||
@ -52,7 +53,7 @@ class PatchtesterModelPull extends JModelLegacy
|
|||||||
*
|
*
|
||||||
* @return array Array of files within a patch
|
* @return array Array of files within a patch
|
||||||
*
|
*
|
||||||
* @since 1.0
|
* @since 2.0
|
||||||
*/
|
*/
|
||||||
protected function parsePatch($patch)
|
protected function parsePatch($patch)
|
||||||
{
|
{
|
||||||
@ -71,7 +72,7 @@ class PatchtesterModelPull extends JModelLegacy
|
|||||||
$state = 1;
|
$state = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
$file = new stdClass;
|
$file = new \stdClass;
|
||||||
$file->action = 'modified';
|
$file->action = 'modified';
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -137,13 +138,13 @@ class PatchtesterModelPull extends JModelLegacy
|
|||||||
*
|
*
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*
|
*
|
||||||
* @since 1.0
|
* @since 2.0
|
||||||
* @throws Exception
|
* @throws \RuntimeException
|
||||||
*/
|
*/
|
||||||
public function apply($id)
|
public function apply($id)
|
||||||
{
|
{
|
||||||
// Get the Github object
|
// Get the Github object
|
||||||
$github = PatchtesterHelper::initializeGithub();
|
$github = Helper::initializeGithub();
|
||||||
|
|
||||||
// Only act if there are API hits remaining
|
// Only act if there are API hits remaining
|
||||||
if ($github->authorization->getRateLimit()->rate->remaining > 0)
|
if ($github->authorization->getRateLimit()->rate->remaining > 0)
|
||||||
@ -152,7 +153,7 @@ class PatchtesterModelPull extends JModelLegacy
|
|||||||
|
|
||||||
if (is_null($pull->head->repo))
|
if (is_null($pull->head->repo))
|
||||||
{
|
{
|
||||||
throw new Exception(JText::_('COM_PATCHTESTER_REPO_IS_GONE'));
|
throw new \RuntimeException(\JText::_('COM_PATCHTESTER_REPO_IS_GONE'));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set up the JHttp object
|
// Set up the JHttp object
|
||||||
@ -161,14 +162,14 @@ class PatchtesterModelPull extends JModelLegacy
|
|||||||
$options->set('timeout', 120);
|
$options->set('timeout', 120);
|
||||||
|
|
||||||
// Make sure we can use the cURL driver
|
// Make sure we can use the cURL driver
|
||||||
$driver = JHttpFactory::getAvailableDriver($options, 'curl');
|
$driver = \JHttpFactory::getAvailableDriver($options, 'curl');
|
||||||
|
|
||||||
if (!($driver instanceof JHttpTransportCurl))
|
if (!($driver instanceof \JHttpTransportCurl))
|
||||||
{
|
{
|
||||||
throw new RuntimeException('Cannot use the PHP cURL adapter in this environment, cannot use patchtester', 500);
|
throw new \RuntimeException('Cannot use the PHP cURL adapter in this environment, cannot use patchtester', 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
$transport = new JHttp($options, $driver);
|
$transport = new \JHttp($options, $driver);
|
||||||
|
|
||||||
$patch = $transport->get($pull->diff_url)->body;
|
$patch = $transport->get($pull->diff_url)->body;
|
||||||
|
|
||||||
@ -176,7 +177,8 @@ class PatchtesterModelPull extends JModelLegacy
|
|||||||
|
|
||||||
if (!$files)
|
if (!$files)
|
||||||
{
|
{
|
||||||
JFactory::getApplication()->enqueueMessage(JText::_('COM_PATCHTESTER_NO_FILES_TO_PATCH', 'message'));
|
// TODO - Should be a better way to enqueue messages without needing the application...
|
||||||
|
\JFactory::getApplication()->enqueueMessage(JText::_('COM_PATCHTESTER_NO_FILES_TO_PATCH', 'message'));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -185,7 +187,7 @@ class PatchtesterModelPull extends JModelLegacy
|
|||||||
{
|
{
|
||||||
if ($file->action == 'deleted' && !file_exists(JPATH_ROOT . '/' . $file->old))
|
if ($file->action == 'deleted' && !file_exists(JPATH_ROOT . '/' . $file->old))
|
||||||
{
|
{
|
||||||
throw new Exception(sprintf(JText::_('COM_PATCHTESTER_FILE_DELETED_DOES_NOT_EXIST_S'), $file->old));
|
throw new \RuntimeException(sprintf(\JText::_('COM_PATCHTESTER_FILE_DELETED_DOES_NOT_EXIST_S'), $file->old));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($file->action == 'added' || $file->action == 'modified')
|
if ($file->action == 'added' || $file->action == 'modified')
|
||||||
@ -193,12 +195,12 @@ class PatchtesterModelPull extends JModelLegacy
|
|||||||
// If the backup file already exists, we can't apply the patch
|
// If the backup file already exists, we can't apply the patch
|
||||||
if (file_exists(JPATH_COMPONENT . '/backups/' . md5($file->new) . '.txt'))
|
if (file_exists(JPATH_COMPONENT . '/backups/' . md5($file->new) . '.txt'))
|
||||||
{
|
{
|
||||||
throw new Exception(sprintf(JText::_('COM_PATCHTESTER_CONFLICT_S'), $file->new));
|
throw new \RuntimeException(sprintf(\JText::_('COM_PATCHTESTER_CONFLICT_S'), $file->new));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($file->action == 'modified' && !file_exists(JPATH_ROOT . '/' . $file->old))
|
if ($file->action == 'modified' && !file_exists(JPATH_ROOT . '/' . $file->old))
|
||||||
{
|
{
|
||||||
throw new Exception(sprintf(JText::_('COM_PATCHTESTER_FILE_MODIFIED_DOES_NOT_EXIST_S'), $file->old));
|
throw new \RuntimeException(sprintf(\JText::_('COM_PATCHTESTER_FILE_MODIFIED_DOES_NOT_EXIST_S'), $file->old));
|
||||||
}
|
}
|
||||||
|
|
||||||
$url = 'https://raw.github.com/' . $pull->head->user->login . '/' . $pull->head->repo->name . '/' . $pull->head->ref . '/' . $file->new;
|
$url = 'https://raw.github.com/' . $pull->head->user->login . '/' . $pull->head->repo->name . '/' . $pull->head->ref . '/' . $file->new;
|
||||||
@ -215,9 +217,9 @@ class PatchtesterModelPull extends JModelLegacy
|
|||||||
// We only create a backup if the file already exists
|
// We only create a backup if the file already exists
|
||||||
if ($file->action == 'deleted' || (file_exists(JPATH_ROOT . '/' . $file->new) && $file->action == 'modified'))
|
if ($file->action == 'deleted' || (file_exists(JPATH_ROOT . '/' . $file->new) && $file->action == 'modified'))
|
||||||
{
|
{
|
||||||
if (!JFile::copy(JPath::clean(JPATH_ROOT . '/' . $file->old), JPATH_COMPONENT . '/backups/' . md5($file->old) . '.txt'))
|
if (!\JFile::copy(\JPath::clean(JPATH_ROOT . '/' . $file->old), JPATH_COMPONENT . '/backups/' . md5($file->old) . '.txt'))
|
||||||
{
|
{
|
||||||
throw new Exception(
|
throw new \RuntimeException(
|
||||||
sprintf('Can not copy file %s to %s', JPATH_ROOT . '/' . $file->old, JPATH_COMPONENT . '/backups/' . md5($file->old) . '.txt')
|
sprintf('Can not copy file %s to %s', JPATH_ROOT . '/' . $file->old, JPATH_COMPONENT . '/backups/' . md5($file->old) . '.txt')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -227,38 +229,38 @@ class PatchtesterModelPull extends JModelLegacy
|
|||||||
{
|
{
|
||||||
case 'modified':
|
case 'modified':
|
||||||
case 'added':
|
case 'added':
|
||||||
if (!JFile::write(JPath::clean(JPATH_ROOT . '/' . $file->new), $file->body))
|
if (!\JFile::write(\JPath::clean(JPATH_ROOT . '/' . $file->new), $file->body))
|
||||||
{
|
{
|
||||||
throw new Exception(sprintf('Can not write the file: %s', JPATH_ROOT . '/' . $file->new));
|
throw new \RuntimeException(sprintf('Can not write the file: %s', JPATH_ROOT . '/' . $file->new));
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'deleted':
|
case 'deleted':
|
||||||
if (!JFile::delete(JPATH::clean(JPATH_ROOT . '/' . $file->old)))
|
if (!\JFile::delete(\JPath::clean(JPATH_ROOT . '/' . $file->old)))
|
||||||
{
|
{
|
||||||
throw new Exception(sprintf('Can not delete the file: %s', JPATH_ROOT . '/' . $file->old));
|
throw new \RuntimeException(sprintf('Can not delete the file: %s', JPATH_ROOT . '/' . $file->old));
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$table = JTable::getInstance('tests', 'PatchTesterTable');
|
$table = \JTable::getInstance('TestsTable', '\\PatchTester\\Table\\');
|
||||||
$table->pull_id = $pull->number;
|
$table->pull_id = $pull->number;
|
||||||
$table->data = json_encode($files);
|
$table->data = json_encode($files);
|
||||||
$table->patched_by = JFactory::getUser()->id;
|
$table->patched_by = \JFactory::getUser()->id;
|
||||||
$table->applied = 1;
|
$table->applied = 1;
|
||||||
$table->applied_version = JVERSION;
|
$table->applied_version = JVERSION;
|
||||||
|
|
||||||
if (!$table->store())
|
if (!$table->store())
|
||||||
{
|
{
|
||||||
throw new Exception($table->getError());
|
throw new \RuntimeException($table->getError());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw new Exception(JText::sprintf('COM_PATCHTESTER_API_LIMIT_ACTION', JFactory::getDate($this->rate->reset)));
|
throw new \RuntimeException(\JText::sprintf('COM_PATCHTESTER_API_LIMIT_ACTION', \JFactory::getDate($this->rate->reset)));
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -271,12 +273,12 @@ class PatchtesterModelPull extends JModelLegacy
|
|||||||
*
|
*
|
||||||
* @return boolean
|
* @return boolean
|
||||||
*
|
*
|
||||||
* @since 1.0
|
* @since 2.0
|
||||||
* @throws Exception
|
* @throws \RuntimeException
|
||||||
*/
|
*/
|
||||||
public function revert($id)
|
public function revert($id)
|
||||||
{
|
{
|
||||||
$table = JTable::getInstance('tests', 'PatchTesterTable');
|
$table = \JTable::getInstance('TestsTable', '\\PatchTester\\Table\\');
|
||||||
$table->load($id);
|
$table->load($id);
|
||||||
|
|
||||||
// We don't want to restore files from an older version
|
// We don't want to restore files from an older version
|
||||||
@ -291,7 +293,7 @@ class PatchtesterModelPull extends JModelLegacy
|
|||||||
|
|
||||||
if (!$files)
|
if (!$files)
|
||||||
{
|
{
|
||||||
throw new Exception(sprintf(JText::_('%s - Error retrieving table data (%s)'), __METHOD__, htmlentities($table->data)));
|
throw new \RuntimeException(sprintf(JText::_('%s - Error retrieving table data (%s)'), __METHOD__, htmlentities($table->data)));
|
||||||
}
|
}
|
||||||
|
|
||||||
jimport('joomla.filesystem.file');
|
jimport('joomla.filesystem.file');
|
||||||
@ -302,28 +304,28 @@ class PatchtesterModelPull extends JModelLegacy
|
|||||||
{
|
{
|
||||||
case 'deleted':
|
case 'deleted':
|
||||||
case 'modified':
|
case 'modified':
|
||||||
if (!JFile::copy(JPATH_COMPONENT . '/backups/' . md5($file->old) . '.txt', JPATH_ROOT . '/' . $file->old))
|
if (!\JFile::copy(JPATH_COMPONENT . '/backups/' . md5($file->old) . '.txt', JPATH_ROOT . '/' . $file->old))
|
||||||
{
|
{
|
||||||
throw new Exception(
|
throw new \RuntimeException(
|
||||||
sprintf(
|
sprintf(
|
||||||
JText::_('Can not copy file %s to %s'),
|
\JText::_('Can not copy file %s to %s'),
|
||||||
JPATH_COMPONENT . '/backups/' . md5($file->old) . '.txt',
|
JPATH_COMPONENT . '/backups/' . md5($file->old) . '.txt',
|
||||||
JPATH_ROOT . '/' . $file->old
|
JPATH_ROOT . '/' . $file->old
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!JFile::delete(JPATH_COMPONENT . '/backups/' . md5($file->old) . '.txt'))
|
if (!\JFile::delete(JPATH_COMPONENT . '/backups/' . md5($file->old) . '.txt'))
|
||||||
{
|
{
|
||||||
throw new Exception(sprintf(JText::_('Can not delete the file: %s'), JPATH_COMPONENT . '/backups/' . md5($file->old) . '.txt'));
|
throw new \RuntimeException(sprintf(\JText::_('Can not delete the file: %s'), JPATH_COMPONENT . '/backups/' . md5($file->old) . '.txt'));
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'added':
|
case 'added':
|
||||||
if (!JFile::delete(JPath::clean(JPATH_ROOT . '/' . $file->new)))
|
if (!\JFile::delete(\JPath::clean(JPATH_ROOT . '/' . $file->new)))
|
||||||
{
|
{
|
||||||
throw new Exception(sprintf(JText::_('Can not delete the file: %s'), JPATH_ROOT . '/' . $file->new));
|
throw new \RuntimeException(sprintf(\JText::_('Can not delete the file: %s'), JPATH_ROOT . '/' . $file->new));
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
@ -0,0 +1,460 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Patch testing component for the Joomla! CMS
|
||||||
|
*
|
||||||
|
* @copyright Copyright (C) 2011 - 2012 Ian MacLennan, Copyright (C) 2013 - 2014 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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Model class for the pulls list view
|
||||||
|
*
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
class PullsModel extends \JModelDatabase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The object context
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
protected $context;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Array of fields the list can be sorted on
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
protected $sortFields = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiate the model.
|
||||||
|
*
|
||||||
|
* @param string $context The model context.
|
||||||
|
* @param Registry $state The model state.
|
||||||
|
* @param \JDatabaseDriver $db The database adpater.
|
||||||
|
*
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public function __construct($context, Registry $state = null, \JDatabaseDriver $db = null)
|
||||||
|
{
|
||||||
|
parent::__construct($state, $db);
|
||||||
|
|
||||||
|
$this->context = $context;
|
||||||
|
$this->sortFields = array('a.pull_id', 'a.title', 'applied');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* @return mixed An array of data items on success, false on failure.
|
||||||
|
*
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public function getItems()
|
||||||
|
{
|
||||||
|
// Get a storage key.
|
||||||
|
$store = $this->getStoreId();
|
||||||
|
|
||||||
|
// Try to load the data from internal storage.
|
||||||
|
if (isset($this->cache[$store]))
|
||||||
|
{
|
||||||
|
return $this->cache[$store];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load the list items.
|
||||||
|
$query = $this->_getListQuery();
|
||||||
|
|
||||||
|
$items = $this->_getList($query, $this->getStart(), $this->getState()->get('list.limit'));
|
||||||
|
|
||||||
|
// Add the items to the internal cache.
|
||||||
|
$this->cache[$store] = $items;
|
||||||
|
|
||||||
|
return $this->cache[$store];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to get a JDatabaseQuery object for retrieving the data set from a database.
|
||||||
|
*
|
||||||
|
* @return \JDatabaseQuery A JDatabaseQuery object to retrieve the data set.
|
||||||
|
*
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
protected function getListQuery()
|
||||||
|
{
|
||||||
|
// Create a new query object.
|
||||||
|
$db = $this->getDb();
|
||||||
|
$query = $db->getQuery(true);
|
||||||
|
|
||||||
|
// Select the required fields from the table.
|
||||||
|
$query->select($this->getState()->get('list.select', 'a.*'));
|
||||||
|
$query->from($db->quoteName('#__patchtester_pulls', 'a'));
|
||||||
|
|
||||||
|
// Join the tests table to get applied patches
|
||||||
|
$query->select($db->quoteName('t.id', 'applied'));
|
||||||
|
$query->join('LEFT', $db->quoteName('#__patchtester_tests', 't') . ' ON t.pull_id = a.pull_id');
|
||||||
|
|
||||||
|
// Filter by search
|
||||||
|
$search = $this->getState()->get('filter.search');
|
||||||
|
|
||||||
|
if (!empty($search))
|
||||||
|
{
|
||||||
|
if (stripos($search, 'id:') === 0)
|
||||||
|
{
|
||||||
|
$query->where($db->quoteName('a.pull_id') . ' = ' . (int) substr($search, 3));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$search = $db->quote('%' . $db->escape($search, true) . '%');
|
||||||
|
$query->where('(' . $db->quoteName('a.title') . ' LIKE ' . $search . ')');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle the list ordering.
|
||||||
|
$ordering = $this->getState()->get('list.ordering');
|
||||||
|
$direction = $this->getState()->get('list.direction');
|
||||||
|
|
||||||
|
if (!empty($ordering))
|
||||||
|
{
|
||||||
|
$query->order($db->escape($ordering) . ' ' . $db->escape($direction));
|
||||||
|
}
|
||||||
|
|
||||||
|
// If $ordering is by applied patches, then append sort on pull_id also
|
||||||
|
if ($ordering === 'applied')
|
||||||
|
{
|
||||||
|
$query->order('a.pull_id ' . $db->escape($direction));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $query;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to get a JPagination object for the data set.
|
||||||
|
*
|
||||||
|
* @return \JPagination A JPagination object for the data set.
|
||||||
|
*
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public function getPagination()
|
||||||
|
{
|
||||||
|
// Get a storage key.
|
||||||
|
$store = $this->getStoreId('getPagination');
|
||||||
|
|
||||||
|
// Try to load the data from internal storage.
|
||||||
|
if (isset($this->cache[$store]))
|
||||||
|
{
|
||||||
|
return $this->cache[$store];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the pagination object.
|
||||||
|
$limit = (int) $this->getState()->get('list.limit') - (int) $this->getState()->get('list.links');
|
||||||
|
$page = new \JPagination($this->getTotal(), $this->getStart(), $limit);
|
||||||
|
|
||||||
|
// Add the object to the internal cache.
|
||||||
|
$this->cache[$store] = $page;
|
||||||
|
|
||||||
|
return $this->cache[$store];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the array of authorized sort fields
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public function getSortFields()
|
||||||
|
{
|
||||||
|
return $this->sortFields;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to get a store id based on the model configuration state.
|
||||||
|
*
|
||||||
|
* This is necessary because the model is used by the component and
|
||||||
|
* different modules that might need different sets of data or different
|
||||||
|
* ordering requirements.
|
||||||
|
*
|
||||||
|
* @param string $id An identifier string to generate the store id.
|
||||||
|
*
|
||||||
|
* @return string A store id.
|
||||||
|
*
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
protected function getStoreId($id = '')
|
||||||
|
{
|
||||||
|
// Add the list state to the store id.
|
||||||
|
$id .= ':' . $this->getState()->get('list.start');
|
||||||
|
$id .= ':' . $this->getState()->get('list.limit');
|
||||||
|
$id .= ':' . $this->getState()->get('list.ordering');
|
||||||
|
$id .= ':' . $this->getState()->get('list.direction');
|
||||||
|
|
||||||
|
return md5($this->context . ':' . $id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to get the starting number of items for the data set.
|
||||||
|
*
|
||||||
|
* @return integer The starting number of items available in the data set.
|
||||||
|
*
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public function getStart()
|
||||||
|
{
|
||||||
|
$store = $this->getStoreId('getStart');
|
||||||
|
|
||||||
|
// Try to load the data from internal storage.
|
||||||
|
if (isset($this->cache[$store]))
|
||||||
|
{
|
||||||
|
return $this->cache[$store];
|
||||||
|
}
|
||||||
|
|
||||||
|
$start = $this->getState()->get('list.start');
|
||||||
|
$limit = $this->getState()->get('list.limit');
|
||||||
|
$total = $this->getTotal();
|
||||||
|
|
||||||
|
if ($start > $total - $limit)
|
||||||
|
{
|
||||||
|
$start = max(0, (int) (ceil($total / $limit) - 1) * $limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the total to the internal cache.
|
||||||
|
$this->cache[$store] = $start;
|
||||||
|
|
||||||
|
return $this->cache[$store];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to get the total number of items for the data set.
|
||||||
|
*
|
||||||
|
* @return integer The total number of items available in the data set.
|
||||||
|
*
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public function getTotal()
|
||||||
|
{
|
||||||
|
// Get a storage key.
|
||||||
|
$store = $this->getStoreId('getTotal');
|
||||||
|
|
||||||
|
// Try to load the data from internal storage.
|
||||||
|
if (isset($this->cache[$store]))
|
||||||
|
{
|
||||||
|
return $this->cache[$store];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load the total.
|
||||||
|
$query = $this->_getListQuery();
|
||||||
|
|
||||||
|
$total = (int) $this->_getListCount($query);
|
||||||
|
|
||||||
|
// Add the total to the internal cache.
|
||||||
|
$this->cache[$store] = $total;
|
||||||
|
|
||||||
|
return $this->cache[$store];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to request new data from GitHub
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
* @since 2.0
|
||||||
|
* @throws \RuntimeException
|
||||||
|
*/
|
||||||
|
public function requestFromGithub()
|
||||||
|
{
|
||||||
|
// Get the Github object
|
||||||
|
$github = Helper::initializeGithub();
|
||||||
|
|
||||||
|
// If over the API limit, we can't build this list
|
||||||
|
if ($github->authorization->getRateLimit()->rate->remaining > 0)
|
||||||
|
{
|
||||||
|
// Sanity check, ensure there aren't any applied patches
|
||||||
|
if (count($this->getAppliedPatches()) >= 1)
|
||||||
|
{
|
||||||
|
throw new \RuntimeException(\JText::_('COM_PATCHTESTER_ERROR_APPLIED_PATCHES'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$pulls = array();
|
||||||
|
$page = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
$page++;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$items = $github->pulls->getList($this->getState()->get('github_user'), $this->getState()->get('github_repo'), 'open', $page, 100);
|
||||||
|
}
|
||||||
|
catch (\DomainException $e)
|
||||||
|
{
|
||||||
|
throw new \RuntimeException(\JText::sprintf('COM_PATCHTESTER_ERROR_GITHUB_FETCH', $e->getMessage()));
|
||||||
|
}
|
||||||
|
|
||||||
|
$count = is_array($items) ? count($items) : 0;
|
||||||
|
|
||||||
|
if ($count)
|
||||||
|
{
|
||||||
|
$pulls = array_merge($pulls, $items);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while ($count);
|
||||||
|
|
||||||
|
// Dump the old data now
|
||||||
|
$this->getDb()->truncateTable('#__patchtester_pulls');
|
||||||
|
|
||||||
|
foreach ($pulls as &$pull)
|
||||||
|
{
|
||||||
|
// Build the data object to store in the database
|
||||||
|
$data = new \stdClass;
|
||||||
|
$data->pull_id = $pull->number;
|
||||||
|
$data->title = $pull->title;
|
||||||
|
$data->description = $pull->body;
|
||||||
|
$data->pull_url = $pull->html_url;
|
||||||
|
|
||||||
|
// Try to find a Joomlacode issue number
|
||||||
|
$matches = array();
|
||||||
|
|
||||||
|
preg_match('#\[\#([0-9]+)\]#', $pull->title, $matches);
|
||||||
|
|
||||||
|
if (isset($matches[1]))
|
||||||
|
{
|
||||||
|
$data->joomlacode_id = (int) $matches[1];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
preg_match('#(http://joomlacode[-\w\./\?\S]+)#', $pull->body, $matches);
|
||||||
|
|
||||||
|
if (isset($matches[1]))
|
||||||
|
{
|
||||||
|
preg_match('#tracker_item_id=([0-9]+)#', $matches[1], $matches);
|
||||||
|
|
||||||
|
if (isset($matches[1]))
|
||||||
|
{
|
||||||
|
$data->joomlacode_id = (int) $matches[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
$this->getDb()->insertObject('#__patchtester_pulls', $data, 'id');
|
||||||
|
}
|
||||||
|
catch (\RuntimeException $e)
|
||||||
|
{
|
||||||
|
throw new \RuntimeException(\JText::sprintf('COM_PATCHTESTER_ERROR_INSERT_DATABASE', $e->getMessage()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new \RuntimeException(\JText::sprintf('COM_PATCHTESTER_API_LIMIT_LIST', \JFactory::getDate($this->rate->reset)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets an array of objects from the results of database query.
|
||||||
|
*
|
||||||
|
* @param \JDatabaseQuery|string $query The query.
|
||||||
|
* @param integer $limitstart Offset.
|
||||||
|
* @param integer $limit The number of records.
|
||||||
|
*
|
||||||
|
* @return array An array of results.
|
||||||
|
*
|
||||||
|
* @since 2.0
|
||||||
|
* @throws RuntimeException
|
||||||
|
*/
|
||||||
|
protected function _getList($query, $limitstart = 0, $limit = 0)
|
||||||
|
{
|
||||||
|
$this->getDb()->setQuery($query, $limitstart, $limit);
|
||||||
|
$result = $this->getDb()->loadObjectList();
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a record count for the query.
|
||||||
|
*
|
||||||
|
* @param \JDatabaseQuery|string $query The query.
|
||||||
|
*
|
||||||
|
* @return integer Number of rows for query.
|
||||||
|
*
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
protected function _getListCount($query)
|
||||||
|
{
|
||||||
|
// Use fast COUNT(*) on JDatabaseQuery objects if there no GROUP BY or HAVING clause:
|
||||||
|
if ($query instanceof \JDatabaseQuery && $query->type == 'select' && $query->group === null && $query->having === null)
|
||||||
|
{
|
||||||
|
$query = clone $query;
|
||||||
|
$query->clear('select')->clear('order')->select('COUNT(*)');
|
||||||
|
|
||||||
|
$this->getDb()->setQuery($query);
|
||||||
|
|
||||||
|
return (int) $this->getDb()->loadResult();
|
||||||
|
}
|
||||||
|
// Otherwise fall back to inefficient way of counting all results.
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$this->getDb()->setQuery($query)->execute();
|
||||||
|
|
||||||
|
return (int) $this->getDb()->getNumRows();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to cache the last query constructed.
|
||||||
|
*
|
||||||
|
* This method ensures that the query is constructed only once for a given state of the model.
|
||||||
|
*
|
||||||
|
* @return \JDatabaseQuery A JDatabaseQuery object
|
||||||
|
*
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
protected function _getListQuery()
|
||||||
|
{
|
||||||
|
// Capture the last store id used.
|
||||||
|
static $lastStoreId;
|
||||||
|
|
||||||
|
// Compute the current store id.
|
||||||
|
$currentStoreId = $this->getStoreId();
|
||||||
|
|
||||||
|
// If the last store id is different from the current, refresh the query.
|
||||||
|
if ($lastStoreId != $currentStoreId || empty($this->query))
|
||||||
|
{
|
||||||
|
$lastStoreId = $currentStoreId;
|
||||||
|
$this->query = $this->getListQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->query;
|
||||||
|
}
|
||||||
|
}
|
@ -1,27 +1,26 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* @package PatchTester
|
* Patch testing component for the Joomla! CMS
|
||||||
*
|
*
|
||||||
* @copyright Copyright (C) 2011 - 2012 Ian MacLennan, Copyright (C) 2013 - 2014 Open Source Matters, Inc. All rights reserved.
|
* @copyright Copyright (C) 2011 - 2012 Ian MacLennan, Copyright (C) 2013 - 2014 Open Source Matters, Inc. All rights reserved.
|
||||||
* @license GNU General Public License version 2 or later
|
* @license GNU General Public License version 2 or later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
defined('_JEXEC') or die;
|
namespace PatchTester\Table;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pulls Table class
|
* Pulls Table class
|
||||||
*
|
*
|
||||||
* @package PatchTester
|
* @since 2.0
|
||||||
* @since 1.0
|
|
||||||
*/
|
*/
|
||||||
class PatchtesterTablePulls extends JTable
|
class PullsTable extends \JTable
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
* @param JDatabaseDriver &$db JDatabaseDriver object.
|
* @param \JDatabaseDriver &$db JDatabaseDriver object.
|
||||||
*
|
*
|
||||||
* @since 1.0
|
* @since 2.0
|
||||||
*/
|
*/
|
||||||
public function __construct(&$db)
|
public function __construct(&$db)
|
||||||
{
|
{
|
@ -1,27 +1,26 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* @package PatchTester
|
* Patch testing component for the Joomla! CMS
|
||||||
*
|
*
|
||||||
* @copyright Copyright (C) 2011 - 2012 Ian MacLennan, Copyright (C) 2013 - 2014 Open Source Matters, Inc. All rights reserved.
|
* @copyright Copyright (C) 2011 - 2012 Ian MacLennan, Copyright (C) 2013 - 2014 Open Source Matters, Inc. All rights reserved.
|
||||||
* @license GNU General Public License version 2 or later
|
* @license GNU General Public License version 2 or later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
defined('_JEXEC') or die;
|
namespace PatchTester\Table;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests Table class
|
* Tests Table class
|
||||||
*
|
*
|
||||||
* @package PatchTester
|
* @since 2.0
|
||||||
* @since 1.0
|
|
||||||
*/
|
*/
|
||||||
class PatchtesterTableTests extends JTable
|
class TestsTable extends \JTable
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
* @param JDatabaseDriver &$db JDatabaseDriver object.
|
* @param \JDatabaseDriver &$db JDatabaseDriver object.
|
||||||
*
|
*
|
||||||
* @since 1.0
|
* @since 2.0
|
||||||
*/
|
*/
|
||||||
public function __construct(&$db)
|
public function __construct(&$db)
|
||||||
{
|
{
|
@ -0,0 +1,62 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Patch testing component for the Joomla! CMS
|
||||||
|
*
|
||||||
|
* @copyright Copyright (C) 2011 - 2012 Ian MacLennan, Copyright (C) 2013 - 2014 Open Source Matters, Inc. All rights reserved.
|
||||||
|
* @license GNU General Public License version 2 or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace PatchTester\View;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default HTML view class.
|
||||||
|
*
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
class DefaultHtmlView extends \JViewHtml
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Load a template file -- first look in the templates folder for an override
|
||||||
|
*
|
||||||
|
* @param string $tpl The name of the template source file; automatically searches the template paths and compiles as needed.
|
||||||
|
*
|
||||||
|
* @return string The output of the the template script.
|
||||||
|
*
|
||||||
|
* @since 2.0
|
||||||
|
* @throws \RuntimeException
|
||||||
|
*/
|
||||||
|
public function loadTemplate($tpl = null)
|
||||||
|
{
|
||||||
|
// Get the path to the file
|
||||||
|
$file = isset($tpl) ? $this->getLayout() . '_' . $tpl : $this->getLayout();
|
||||||
|
$path = $this->getPath($file);
|
||||||
|
|
||||||
|
if ($path)
|
||||||
|
{
|
||||||
|
// Unset so as not to introduce into template scope
|
||||||
|
unset($tpl);
|
||||||
|
unset($file);
|
||||||
|
|
||||||
|
// Never allow a 'this' property
|
||||||
|
if (isset($this->this))
|
||||||
|
{
|
||||||
|
unset($this->this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start an output buffer.
|
||||||
|
ob_start();
|
||||||
|
|
||||||
|
// Load the template.
|
||||||
|
include $path;
|
||||||
|
|
||||||
|
// Get the layout contents.
|
||||||
|
$output = ob_get_clean();
|
||||||
|
|
||||||
|
return $output;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new \RuntimeException(\JText::sprintf('JLIB_APPLICATION_ERROR_LAYOUTFILE_NOT_FOUND', $file), 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,126 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Patch testing component for the Joomla! CMS
|
||||||
|
*
|
||||||
|
* @copyright Copyright (C) 2011 - 2012 Ian MacLennan, Copyright (C) 2013 - 2014 Open Source Matters, Inc. All rights reserved.
|
||||||
|
* @license GNU General Public License version 2 or later
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace PatchTester\View\Pulls;
|
||||||
|
|
||||||
|
use PatchTester\View\DefaultHtmlView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* View class for a list of pull requests.
|
||||||
|
*
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
class PullsHtmlView extends DefaultHtmlView
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Array containing environment errors
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
protected $envErrors = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Array of open pull requests
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
protected $items;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The model object - redeclared for proper type hinting.
|
||||||
|
*
|
||||||
|
* @var \PatchTester\Model\PullsModel
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
protected $model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* State object
|
||||||
|
*
|
||||||
|
* @var \Joomla\Registry\Registry
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
protected $state;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pagination object
|
||||||
|
*
|
||||||
|
* @var \JPagination
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
protected $pagination;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to render the view.
|
||||||
|
*
|
||||||
|
* @return string The rendered view.
|
||||||
|
*
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
public function render()
|
||||||
|
{
|
||||||
|
if (!extension_loaded('openssl'))
|
||||||
|
{
|
||||||
|
$this->envErrors[] = \JText::_('COM_PATCHTESTER_REQUIREMENT_OPENSSL');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!in_array('https', stream_get_wrappers()))
|
||||||
|
{
|
||||||
|
$this->envErrors[] = \JText::_('COM_PATCHTESTER_REQUIREMENT_HTTPS');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only process the data if there are no environment errors
|
||||||
|
if (!count($this->envErrors))
|
||||||
|
{
|
||||||
|
$this->state = $this->model->getState();
|
||||||
|
$this->items = $this->model->getItems();
|
||||||
|
$this->pagination = $this->model->getPagination();
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->addToolbar();
|
||||||
|
|
||||||
|
return parent::render();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the page title and toolbar.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
protected function addToolbar()
|
||||||
|
{
|
||||||
|
\JToolBarHelper::title(\JText::_('COM_PATCHTESTER'), 'patchtester');
|
||||||
|
|
||||||
|
if (!count($this->envErrors))
|
||||||
|
{
|
||||||
|
\JToolbarHelper::custom('pulls.fetch', 'refresh.png', 'refresh_f2.png', 'COM_PATCHTESTER_TOOLBAR_FETCH_DATA', false);
|
||||||
|
}
|
||||||
|
|
||||||
|
\JToolBarHelper::preferences('com_patchtester');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an array of fields the table can be sorted by
|
||||||
|
*
|
||||||
|
* @return array Array containing the field name to sort by as the key and display text as value
|
||||||
|
*
|
||||||
|
* @since 2.0
|
||||||
|
*/
|
||||||
|
protected function getSortFields()
|
||||||
|
{
|
||||||
|
return array(
|
||||||
|
'a.title' => \JText::_('JGLOBAL_TITLE'),
|
||||||
|
'a.pull_id' => \JText::_('COM_PATCHTESTER_PULL_ID'),
|
||||||
|
'applied' => \JText::_('JSTATUS')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -1,17 +1,15 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* @package PatchTester
|
* Patch testing component for the Joomla! CMS
|
||||||
*
|
*
|
||||||
* @copyright Copyright (C) 2011 - 2012 Ian MacLennan, Copyright (C) 2013 - 2014 Open Source Matters, Inc. All rights reserved.
|
* @copyright Copyright (C) 2011 - 2012 Ian MacLennan, Copyright (C) 2013 - 2014 Open Source Matters, Inc. All rights reserved.
|
||||||
* @license GNU General Public License version 2 or later
|
* @license GNU General Public License version 2 or later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
defined('_JEXEC') or die;
|
/** @type \PatchTester\View\Pulls\PullsHtmlView $this */
|
||||||
|
|
||||||
/** @type PatchtesterViewPulls $this */
|
\JHtml::_('behavior.tooltip');
|
||||||
|
\JHtml::_('behavior.modal');
|
||||||
JHtml::_('behavior.tooltip');
|
|
||||||
JHtml::_('behavior.modal');
|
|
||||||
|
|
||||||
$listOrder = $this->escape($this->state->get('list.ordering'));
|
$listOrder = $this->escape($this->state->get('list.ordering'));
|
||||||
$listDirn = $this->escape($this->state->get('list.direction'));
|
$listDirn = $this->escape($this->state->get('list.direction'));
|
||||||
@ -41,36 +39,36 @@ else :
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<form action="<?php echo JRoute::_('index.php?option=com_patchtester&view=pulls'); ?>" method="post" name="adminForm" id="adminForm">
|
<form action="<?php echo \JRoute::_('index.php?option=com_patchtester&view=pulls'); ?>" method="post" name="adminForm" id="adminForm">
|
||||||
<div id="filter-bar" class="btn-toolbar">
|
<div id="filter-bar" class="btn-toolbar">
|
||||||
<div class="btn-group pull-right">
|
<div class="btn-group pull-right">
|
||||||
<label for="sortTable" class="element-invisible"><?php echo JText::_('JGLOBAL_SORT_BY'); ?></label>
|
<label for="sortTable" class="element-invisible"><?php echo \JText::_('JGLOBAL_SORT_BY'); ?></label>
|
||||||
<select name="sortTable" id="sortTable" class="input-medium" onchange="Joomla.orderTable()">
|
<select name="sortTable" id="sortTable" class="input-medium" onchange="Joomla.orderTable()">
|
||||||
<option value=""><?php echo JText::_('JGLOBAL_SORT_BY'); ?></option>
|
<option value=""><?php echo \JText::_('JGLOBAL_SORT_BY'); ?></option>
|
||||||
<?php echo JHtml::_('select.options', $sortFields, 'value', 'text', $listOrder);?>
|
<?php echo \JHtml::_('select.options', $sortFields, 'value', 'text', $listOrder);?>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="j-main-container">
|
<div id="j-main-container">
|
||||||
<div id="filter-bar" class="btn-toolbar">
|
<div id="filter-bar" class="btn-toolbar">
|
||||||
<div class="filter-search btn-group pull-left">
|
<div class="filter-search btn-group pull-left">
|
||||||
<label for="filter_search" class="element-invisible"><?php echo JText::_('COM_PATCHTESTER_FILTER_SEARCH_DESCRIPTION'); ?></label>
|
<label for="filter_search" class="element-invisible"><?php echo \JText::_('COM_PATCHTESTER_FILTER_SEARCH_DESCRIPTION'); ?></label>
|
||||||
<input type="text" name="filter_search" placeholder="<?php echo JText::_('COM_PATCHTESTER_FILTER_SEARCH_DESCRIPTION'); ?>" id="filter_search" value="<?php echo $this->escape($this->state->get('filter.search')); ?>" title="<?php echo JText::_('COM_PATCHTESTER_FILTER_SEARCH_DESCRIPTION'); ?>" />
|
<input type="text" name="filter_search" placeholder="<?php echo \JText::_('COM_PATCHTESTER_FILTER_SEARCH_DESCRIPTION'); ?>" id="filter_search" value="<?php echo $this->escape($this->state->get('filter.search')); ?>" title="<?php echo \JText::_('COM_PATCHTESTER_FILTER_SEARCH_DESCRIPTION'); ?>" />
|
||||||
</div>
|
</div>
|
||||||
<div class="btn-group pull-left hidden-phone">
|
<div class="btn-group pull-left hidden-phone">
|
||||||
<button class="btn tip hasTooltip" type="submit" title="<?php echo JText::_('JSEARCH_FILTER_SUBMIT'); ?>"><i class="icon-search"></i></button>
|
<button class="btn tip hasTooltip" type="submit" title="<?php echo \JText::_('JSEARCH_FILTER_SUBMIT'); ?>"><i class="icon-search"></i></button>
|
||||||
<button class="btn tip hasTooltip" type="button" onclick="document.id('filter_search').value='';this.form.submit();" title="<?php echo JText::_('JSEARCH_FILTER_CLEAR'); ?>"><i class="icon-remove"></i></button>
|
<button class="btn tip hasTooltip" type="button" onclick="document.id('filter_search').value='';this.form.submit();" title="<?php echo \JText::_('JSEARCH_FILTER_CLEAR'); ?>"><i class="icon-remove"></i></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="btn-group pull-right hidden-phone">
|
<div class="btn-group pull-right hidden-phone">
|
||||||
<label for="limit" class="element-invisible"><?php echo JText::_('JFIELD_PLG_SEARCH_SEARCHLIMIT_DESC'); ?></label>
|
<label for="limit" class="element-invisible"><?php echo \JText::_('JFIELD_PLG_SEARCH_SEARCHLIMIT_DESC'); ?></label>
|
||||||
<?php echo $this->pagination->getLimitBox(); ?>
|
<?php echo $this->pagination->getLimitBox(); ?>
|
||||||
</div>
|
</div>
|
||||||
<div class="btn-group pull-right hidden-phone">
|
<div class="btn-group pull-right hidden-phone">
|
||||||
<label for="directionTable" class="element-invisible"><?php echo JText::_('JFIELD_ORDERING_DESC'); ?></label>
|
<label for="directionTable" class="element-invisible"><?php echo \JText::_('JFIELD_ORDERING_DESC'); ?></label>
|
||||||
<select name="directionTable" id="directionTable" class="input-medium" onchange="Joomla.orderTable()">
|
<select name="directionTable" id="directionTable" class="input-medium" onchange="Joomla.orderTable()">
|
||||||
<option value=""><?php echo JText::_('JFIELD_ORDERING_DESC');?></option>
|
<option value=""><?php echo \JText::_('JFIELD_ORDERING_DESC');?></option>
|
||||||
<option value="asc" <?php if ($listDirn == 'asc') echo 'selected="selected"'; ?>><?php echo JText::_('JGLOBAL_ORDER_ASCENDING'); ?></option>
|
<option value="asc" <?php if ($listDirn == 'asc') echo 'selected="selected"'; ?>><?php echo \JText::_('JGLOBAL_ORDER_ASCENDING'); ?></option>
|
||||||
<option value="desc" <?php if ($listDirn == 'desc') echo 'selected="selected"'; ?>><?php echo JText::_('JGLOBAL_ORDER_DESCENDING'); ?></option>
|
<option value="desc" <?php if ($listDirn == 'desc') echo 'selected="selected"'; ?>><?php echo \JText::_('JGLOBAL_ORDER_DESCENDING'); ?></option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -80,20 +78,20 @@ else :
|
|||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th width="5%" class="nowrap center">
|
<th width="5%" class="nowrap center">
|
||||||
<?php echo JText::_('COM_PATCHTESTER_PULL_ID'); ?>
|
<?php echo \JText::_('COM_PATCHTESTER_PULL_ID'); ?>
|
||||||
</th>
|
</th>
|
||||||
<th class="nowrap center">
|
<th class="nowrap center">
|
||||||
<?php echo JText::_('JGLOBAL_TITLE'); ?>
|
<?php echo \JText::_('JGLOBAL_TITLE'); ?>
|
||||||
</th>
|
</th>
|
||||||
<th class="nowrap center">I</th>
|
<th class="nowrap center">I</th>
|
||||||
<th class="nowrap center">
|
<th class="nowrap center">
|
||||||
<?php echo JText::_('COM_PATCHTESTER_JOOMLACODE_ISSUE'); ?>
|
<?php echo \JText::_('COM_PATCHTESTER_JOOMLACODE_ISSUE'); ?>
|
||||||
</th>
|
</th>
|
||||||
<th width="20%" class="nowrap center">
|
<th width="20%" class="nowrap center">
|
||||||
<?php echo JText::_('JSTATUS'); ?>
|
<?php echo \JText::_('JSTATUS'); ?>
|
||||||
</th>
|
</th>
|
||||||
<th width="20%" class="nowrap center">
|
<th width="20%" class="nowrap center">
|
||||||
<?php echo JText::_('COM_PATCHTESTER_TEST_THIS_PATCH'); ?>
|
<?php echo \JText::_('COM_PATCHTESTER_TEST_THIS_PATCH'); ?>
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
@ -107,7 +105,7 @@ else :
|
|||||||
<?php if (count($this->items)) :
|
<?php if (count($this->items)) :
|
||||||
echo $this->loadTemplate('items');
|
echo $this->loadTemplate('items');
|
||||||
else : ?>
|
else : ?>
|
||||||
<td align="center" colspan="6"><?php echo JText::_('COM_PATCHTESTER_NO_ITEMS'); ?></td>
|
<td align="center" colspan="6"><?php echo \JText::_('COM_PATCHTESTER_NO_ITEMS'); ?></td>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
@ -118,7 +116,7 @@ else :
|
|||||||
<input type="hidden" name="pull_id" id="pull_id" value=""/>
|
<input type="hidden" name="pull_id" id="pull_id" value=""/>
|
||||||
<input type="hidden" name="filter_order" value="<?php echo $listOrder; ?>"/>
|
<input type="hidden" name="filter_order" value="<?php echo $listOrder; ?>"/>
|
||||||
<input type="hidden" name="filter_order_Dir" value="<?php echo $listDirn; ?>"/>
|
<input type="hidden" name="filter_order_Dir" value="<?php echo $listDirn; ?>"/>
|
||||||
<?php echo JHtml::_('form.token'); ?>
|
<?php echo \JHtml::_('form.token'); ?>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<?php endif;
|
<?php endif;
|
@ -1,17 +1,15 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* @package PatchTester
|
* Patch testing component for the Joomla! CMS
|
||||||
*
|
*
|
||||||
* @copyright Copyright (C) 2011 - 2012 Ian MacLennan, Copyright (C) 2013 - 2014 Open Source Matters, Inc. All rights reserved.
|
* @copyright Copyright (C) 2011 - 2012 Ian MacLennan, Copyright (C) 2013 - 2014 Open Source Matters, Inc. All rights reserved.
|
||||||
* @license GNU General Public License version 2 or later
|
* @license GNU General Public License version 2 or later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
defined('_JEXEC') or die;
|
/** @type \PatchTester\View\Pulls\PullsHtmlView $this */
|
||||||
|
|
||||||
/** @type PatchtesterViewPulls $this */
|
|
||||||
?>
|
?>
|
||||||
<h3><?php echo JText::_('COM_PATCHTESTER_REQUIREMENTS_HEADING'); ?></h3>
|
<h3><?php echo \JText::_('COM_PATCHTESTER_REQUIREMENTS_HEADING'); ?></h3>
|
||||||
<p><?php echo JText::_('COM_PATCHTESTER_REQUIREMENTS_NOT_MET'); ?></p>
|
<p><?php echo \JText::_('COM_PATCHTESTER_REQUIREMENTS_NOT_MET'); ?></p>
|
||||||
<ul>
|
<ul>
|
||||||
<?php foreach ($this->envErrors as $error) : ?>
|
<?php foreach ($this->envErrors as $error) : ?>
|
||||||
<li><?php echo $error; ?></li>
|
<li><?php echo $error; ?></li>
|
@ -1,14 +1,12 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* @package PatchTester
|
* Patch testing component for the Joomla! CMS
|
||||||
*
|
*
|
||||||
* @copyright Copyright (C) 2011 - 2012 Ian MacLennan, Copyright (C) 2013 - 2014 Open Source Matters, Inc. All rights reserved.
|
* @copyright Copyright (C) 2011 - 2012 Ian MacLennan, Copyright (C) 2013 - 2014 Open Source Matters, Inc. All rights reserved.
|
||||||
* @license GNU General Public License version 2 or later
|
* @license GNU General Public License version 2 or later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
defined('_JEXEC') or die;
|
/** @type \PatchTester\View\Pulls\PullsHtmlView $this */
|
||||||
|
|
||||||
/** @type PatchtesterViewPulls $this */
|
|
||||||
|
|
||||||
foreach ($this->items as $i => $item) :
|
foreach ($this->items as $i => $item) :
|
||||||
$status = '';
|
$status = '';
|
||||||
@ -22,13 +20,13 @@ foreach ($this->items as $i => $item) :
|
|||||||
<?php echo $item->pull_id; ?>
|
<?php echo $item->pull_id; ?>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<a class="icon icon16-github hasTip" title="<?php echo JText::_('COM_PATCHTESTER_OPEN_IN_GITHUB'); ?>" href="<?php echo $item->pull_url; ?>" target="_blank">
|
<a class="icon icon16-github hasTip" title="<?php echo \JText::_('COM_PATCHTESTER_OPEN_IN_GITHUB'); ?>" href="<?php echo $item->pull_url; ?>" target="_blank">
|
||||||
<?php echo $this->escape($item->title); ?>
|
<?php echo $this->escape($item->title); ?>
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<?php if ($item->description) :
|
<?php if ($item->description) :
|
||||||
echo JHtml::_('tooltip', htmlspecialchars($item->description), 'Info');
|
echo \JHtml::_('tooltip', $this->escape(($item->description)), 'Info');
|
||||||
else :
|
else :
|
||||||
echo ' ';
|
echo ' ';
|
||||||
endif;
|
endif;
|
||||||
@ -36,7 +34,7 @@ foreach ($this->items as $i => $item) :
|
|||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<?php if ($item->joomlacode_id) :
|
<?php if ($item->joomlacode_id) :
|
||||||
$title = ' title="Open link::' . JText::_('COM_PATCHTESTER_OPEN_IN_JOOMLACODE') . '"';
|
$title = ' title="Open link::' . \JText::_('COM_PATCHTESTER_OPEN_IN_JOOMLACODE') . '"';
|
||||||
|
|
||||||
echo '<a href="http://joomlacode.org/gf/project/joomla/tracker/?action=TrackerItemEdit&tracker_item_id=';
|
echo '<a href="http://joomlacode.org/gf/project/joomla/tracker/?action=TrackerItemEdit&tracker_item_id=';
|
||||||
echo $item->joomlacode_id . '"' . $title . ' class="modal hasTip" rel="{handler: \'iframe\', size: {x: 900, y: 500}}">';
|
echo $item->joomlacode_id . '"' . $title . ' class="modal hasTip" rel="{handler: \'iframe\', size: {x: 900, y: 500}}">';
|
||||||
@ -46,19 +44,19 @@ foreach ($this->items as $i => $item) :
|
|||||||
<td class="center">
|
<td class="center">
|
||||||
<?php if ($item->applied) : ?>
|
<?php if ($item->applied) : ?>
|
||||||
<span class="label label-success">
|
<span class="label label-success">
|
||||||
<?php echo JText::_('COM_PATCHTESTER_APPLIED'); ?>
|
<?php echo \JText::_('COM_PATCHTESTER_APPLIED'); ?>
|
||||||
</span>
|
</span>
|
||||||
<?php else : ?>
|
<?php else : ?>
|
||||||
<span class="label">
|
<span class="label">
|
||||||
<?php echo JText::_('COM_PATCHTESTER_NOT_APPLIED'); ?>
|
<?php echo \JText::_('COM_PATCHTESTER_NOT_APPLIED'); ?>
|
||||||
</span>
|
</span>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
</td>
|
</td>
|
||||||
<td class="center">
|
<td class="center">
|
||||||
<?php if ($item->applied) :
|
<?php if ($item->applied) :
|
||||||
echo '<a class="btn btn-small btn-success" href="javascript:submitpatch(\'pull.revert\', ' . (int) $item->applied . ');">' . JText::_('COM_PATCHTESTER_REVERT_PATCH') . '</a>';
|
echo '<a class="btn btn-small btn-success" href="javascript:submitpatch(\'pull.revert\', ' . (int) $item->applied . ');">' . \JText::_('COM_PATCHTESTER_REVERT_PATCH') . '</a>';
|
||||||
else :
|
else :
|
||||||
echo '<a class="btn btn-small btn-primary" href="javascript:submitpatch(\'pull.apply\', ' . (int) $item->pull_id . ');">' . JText::_('COM_PATCHTESTER_APPLY_PATCH') . '</a>';
|
echo '<a class="btn btn-small btn-primary" href="javascript:submitpatch(\'pull.apply\', ' . (int) $item->pull_id . ');">' . \JText::_('COM_PATCHTESTER_APPLY_PATCH') . '</a>';
|
||||||
endif; ?>
|
endif; ?>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
@ -1,26 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* @package PatchTester
|
|
||||||
*
|
|
||||||
* @copyright Copyright (C) 2011 - 2012 Ian MacLennan, Copyright (C) 2013 - 2014 Open Source Matters, Inc. All rights reserved.
|
|
||||||
* @license GNU General Public License version 2 or later
|
|
||||||
*/
|
|
||||||
|
|
||||||
defined('_JEXEC') or die;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* PatchTester Controller
|
|
||||||
*
|
|
||||||
* @package PatchTester
|
|
||||||
* @since 1.0
|
|
||||||
*/
|
|
||||||
class PatchTesterController extends JControllerLegacy
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* The default view for the display method.
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
* @since 1.0
|
|
||||||
*/
|
|
||||||
protected $default_view = 'pulls';
|
|
||||||
}
|
|
@ -1,68 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* @package PatchTester
|
|
||||||
*
|
|
||||||
* @copyright Copyright (C) 2011 - 2012 Ian MacLennan, Copyright (C) 2013 - 2014 Open Source Matters, Inc. All rights reserved.
|
|
||||||
* @license GNU General Public License version 2 or later
|
|
||||||
*/
|
|
||||||
|
|
||||||
defined('_JEXEC') or die;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Pull controller class
|
|
||||||
*
|
|
||||||
* @package PatchTester
|
|
||||||
* @since 1.0
|
|
||||||
*/
|
|
||||||
class PatchtesterControllerPull extends JControllerLegacy
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Method to apply a patch
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*
|
|
||||||
* @since 1.0
|
|
||||||
*/
|
|
||||||
public function apply()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
$this->getModel('pull')->apply(JFactory::getApplication()->input->getInt('pull_id'));
|
|
||||||
|
|
||||||
$msg = JText::_('COM_PATCHTESTER_APPLY_OK');
|
|
||||||
$type = 'message';
|
|
||||||
}
|
|
||||||
catch (Exception $e)
|
|
||||||
{
|
|
||||||
$msg = $e->getMessage();
|
|
||||||
$type = 'error';
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->setRedirect(JRoute::_('index.php?option=com_patchtester&view=pulls', false), $msg, $type);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method to revert a patch
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*
|
|
||||||
* @since 1.0
|
|
||||||
*/
|
|
||||||
public function revert()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
$this->getModel('pull')->revert(JFactory::getApplication()->input->getInt('pull_id'));
|
|
||||||
|
|
||||||
$msg = JText::_('COM_PATCHTESTER_REVERT_OK');
|
|
||||||
$type = 'message';
|
|
||||||
}
|
|
||||||
catch (Exception $e)
|
|
||||||
{
|
|
||||||
$msg = $e->getMessage();
|
|
||||||
$type = 'error';
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->setRedirect(JRoute::_('index.php?option=com_patchtester&view=pulls', false), $msg, $type);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,43 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* @package PatchTester
|
|
||||||
*
|
|
||||||
* @copyright Copyright (C) 2011 - 2012 Ian MacLennan, Copyright (C) 2013 - 2014 Open Source Matters, Inc. All rights reserved.
|
|
||||||
* @license GNU General Public License version 2 or later
|
|
||||||
*/
|
|
||||||
|
|
||||||
defined('_JEXEC') or die;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Pulls controller class
|
|
||||||
*
|
|
||||||
* @package PatchTester
|
|
||||||
* @since 2.0
|
|
||||||
*/
|
|
||||||
class PatchtesterControllerPulls extends JControllerLegacy
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Fetch pull request data from GitHub
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*
|
|
||||||
* @since 2.0
|
|
||||||
*/
|
|
||||||
public function fetch()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
$this->getModel('pulls')->requestFromGithub();
|
|
||||||
|
|
||||||
$msg = JText::_('COM_PATCHTESTER_FETCH_SUCCESSFUL');
|
|
||||||
$type = 'message';
|
|
||||||
}
|
|
||||||
catch (Exception $e)
|
|
||||||
{
|
|
||||||
$msg = $e->getMessage();
|
|
||||||
$type = 'error';
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->setRedirect(JRoute::_('index.php?option=com_patchtester&view=pulls', false), $msg, $type);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,246 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* @package PatchTester
|
|
||||||
*
|
|
||||||
* @copyright Copyright (C) 2011 - 2012 Ian MacLennan, Copyright (C) 2013 - 2014 Open Source Matters, Inc. All rights reserved.
|
|
||||||
* @license GNU General Public License version 2 or later
|
|
||||||
*/
|
|
||||||
|
|
||||||
defined('_JEXEC') or die;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Methods supporting a list of pull requests.
|
|
||||||
*
|
|
||||||
* @package PatchTester
|
|
||||||
* @since 1.0
|
|
||||||
*/
|
|
||||||
class PatchtesterModelPulls extends JModelList
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Constructor.
|
|
||||||
*
|
|
||||||
* @param array $config An optional associative array of configuration settings.
|
|
||||||
*
|
|
||||||
* @see JControllerLegacy
|
|
||||||
* @since 1.0
|
|
||||||
*/
|
|
||||||
public function __construct($config = array())
|
|
||||||
{
|
|
||||||
if (empty($config['filter_fields']))
|
|
||||||
{
|
|
||||||
$config['filter_fields'] = array(
|
|
||||||
'id', 'title', 'applied'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
parent::__construct($config);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method to auto-populate the model state.
|
|
||||||
*
|
|
||||||
* @param string $ordering An optional ordering field.
|
|
||||||
* @param string $direction An optional direction (asc|desc).
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*
|
|
||||||
* @note Calling getState() in this method will result in recursion.
|
|
||||||
* @since 1.0
|
|
||||||
*/
|
|
||||||
protected function populateState($ordering = null, $direction = null)
|
|
||||||
{
|
|
||||||
// Load the filter state.
|
|
||||||
$search = $this->getUserStateFromRequest($this->context . '.filter.search', 'filter_search', '');
|
|
||||||
$this->setState('filter.search', $search);
|
|
||||||
|
|
||||||
// Load the parameters.
|
|
||||||
$params = JComponentHelper::getParams('com_patchtester');
|
|
||||||
|
|
||||||
$this->setState('params', $params);
|
|
||||||
$this->setState('github_user', $params->get('org', 'joomla'));
|
|
||||||
$this->setState('github_repo', $params->get('repo', 'joomla-cms'));
|
|
||||||
|
|
||||||
// List state information.
|
|
||||||
parent::populateState('a.pull_id', 'desc');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves a list of applied patches
|
|
||||||
*
|
|
||||||
* @return mixed
|
|
||||||
*
|
|
||||||
* @since 1.0
|
|
||||||
*/
|
|
||||||
public function getAppliedPatches()
|
|
||||||
{
|
|
||||||
$db = $this->getDbo();
|
|
||||||
|
|
||||||
$db->setQuery(
|
|
||||||
$db->getQuery(true)
|
|
||||||
->select('*')
|
|
||||||
->from($db->quoteName('#__patchtester_tests'))
|
|
||||||
->where($db->quoteName('applied') . ' = 1')
|
|
||||||
);
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
$tests = $db->loadObjectList('pull_id');
|
|
||||||
|
|
||||||
return $tests;
|
|
||||||
}
|
|
||||||
catch (RuntimeException $e)
|
|
||||||
{
|
|
||||||
$this->setError($e->getMessage());
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method to get a JDatabaseQuery object for retrieving the data set from a database.
|
|
||||||
*
|
|
||||||
* @return JDatabaseQuery A JDatabaseQuery object to retrieve the data set.
|
|
||||||
*
|
|
||||||
* @since 2.0
|
|
||||||
*/
|
|
||||||
protected function getListQuery()
|
|
||||||
{
|
|
||||||
// Create a new query object.
|
|
||||||
$db = $this->getDbo();
|
|
||||||
$query = $db->getQuery(true);
|
|
||||||
|
|
||||||
// Select the required fields from the table.
|
|
||||||
$query->select($this->getState('list.select', 'a.*'));
|
|
||||||
$query->from($db->quoteName('#__patchtester_pulls', 'a'));
|
|
||||||
|
|
||||||
// Join the tests table to get applied patches
|
|
||||||
$query->select($db->quoteName('t.id', 'applied'));
|
|
||||||
$query->join('LEFT', $db->quoteName('#__patchtester_tests', 't') . ' ON t.pull_id = a.pull_id');
|
|
||||||
|
|
||||||
// Filter by search
|
|
||||||
$search = $this->getState('filter.search');
|
|
||||||
|
|
||||||
if (!empty($search))
|
|
||||||
{
|
|
||||||
if (stripos($search, 'id:') === 0)
|
|
||||||
{
|
|
||||||
$query->where($db->quoteName('a.pull_id') . ' = ' . (int) substr($search, 3));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$search = $db->quote('%' . $db->escape($search, true) . '%');
|
|
||||||
$query->where('(' . $db->quoteName('a.title') . ' LIKE ' . $search . ')');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle the list ordering.
|
|
||||||
$ordering = $this->getState('list.ordering');
|
|
||||||
$direction = $this->getState('list.direction');
|
|
||||||
|
|
||||||
if (!empty($ordering))
|
|
||||||
{
|
|
||||||
$query->order($db->escape($ordering) . ' ' . $db->escape($direction));
|
|
||||||
}
|
|
||||||
|
|
||||||
return $query;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method to request new data from GitHub
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*
|
|
||||||
* @since 2.0
|
|
||||||
* @throws RuntimeException
|
|
||||||
*/
|
|
||||||
public function requestFromGithub()
|
|
||||||
{
|
|
||||||
// Get the Github object
|
|
||||||
$github = PatchtesterHelper::initializeGithub();
|
|
||||||
|
|
||||||
// If over the API limit, we can't build this list
|
|
||||||
if ($github->authorization->getRateLimit()->rate->remaining > 0)
|
|
||||||
{
|
|
||||||
// Sanity check, ensure there aren't any applied patches
|
|
||||||
if (count($this->getAppliedPatches()) >= 1)
|
|
||||||
{
|
|
||||||
throw new RuntimeException(JText::_('COM_PATCHTESTER_ERROR_APPLIED_PATCHES'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$pulls = array();
|
|
||||||
$page = 0;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
$page++;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
$items = $github->pulls->getList($this->getState('github_user'), $this->getState('github_repo'), 'open', $page, 100);
|
|
||||||
}
|
|
||||||
catch (DomainException $e)
|
|
||||||
{
|
|
||||||
throw new RuntimeException(JText::sprintf('COM_PATCHTESTER_ERROR_GITHUB_FETCH', $e->getMessage()));
|
|
||||||
}
|
|
||||||
|
|
||||||
$count = is_array($items) ? count($items) : 0;
|
|
||||||
|
|
||||||
if ($count)
|
|
||||||
{
|
|
||||||
$pulls = array_merge($pulls, $items);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while ($count);
|
|
||||||
|
|
||||||
// Dump the old data now
|
|
||||||
$this->getDbo()->truncateTable('#__patchtester_pulls');
|
|
||||||
|
|
||||||
foreach ($pulls as &$pull)
|
|
||||||
{
|
|
||||||
// Build the data object to store in the database
|
|
||||||
$data = new stdClass;
|
|
||||||
$data->pull_id = $pull->number;
|
|
||||||
$data->title = $pull->title;
|
|
||||||
$data->description = $pull->body;
|
|
||||||
$data->pull_url = $pull->html_url;
|
|
||||||
|
|
||||||
// Try to find a Joomlacode issue number
|
|
||||||
$matches = array();
|
|
||||||
|
|
||||||
preg_match('#\[\#([0-9]+)\]#', $pull->title, $matches);
|
|
||||||
|
|
||||||
if (isset($matches[1]))
|
|
||||||
{
|
|
||||||
$data->joomlacode_id = (int) $matches[1];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
preg_match('#(http://joomlacode[-\w\./\?\S]+)#', $pull->body, $matches);
|
|
||||||
|
|
||||||
if (isset($matches[1]))
|
|
||||||
{
|
|
||||||
preg_match('#tracker_item_id=([0-9]+)#', $matches[1], $matches);
|
|
||||||
|
|
||||||
if (isset($matches[1]))
|
|
||||||
{
|
|
||||||
$data->joomlacode_id = (int) $matches[1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
$this->getDbo()->insertObject('#__patchtester_pulls', $data, 'id');
|
|
||||||
}
|
|
||||||
catch (RuntimeException $e)
|
|
||||||
{
|
|
||||||
throw new RuntimeException(JText::sprintf('COM_PATCHTESTER_ERROR_INSERT_DATABASE', $e->getMessage()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new RuntimeException(JText::sprintf('COM_PATCHTESTER_API_LIMIT_LIST', JFactory::getDate($this->rate->reset)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -14,8 +14,23 @@ if (!JFactory::getUser()->authorise('core.manage', 'com_patchtester'))
|
|||||||
return JError::raiseWarning(404, JText::_('JERROR_ALERTNOAUTHOR'));
|
return JError::raiseWarning(404, JText::_('JERROR_ALERTNOAUTHOR'));
|
||||||
}
|
}
|
||||||
|
|
||||||
JLoader::register('PatchtesterHelper', __DIR__ . '/helpers/patchtester.php');
|
// Application reference
|
||||||
|
$app = JFactory::getApplication();
|
||||||
|
|
||||||
$controller = JControllerLegacy::getInstance('PatchTester');
|
// Register the component namespace to the autoloader
|
||||||
$controller->execute(JFactory::getApplication()->input->getCmd('task'));
|
JLoader::registerNamespace('PatchTester', __DIR__);
|
||||||
$controller->redirect();
|
|
||||||
|
// Build the controller class name based on task
|
||||||
|
$task = $app->input->getCmd('task', 'display');
|
||||||
|
|
||||||
|
// If $task is an empty string, apply our default since JInput might not
|
||||||
|
if ($task === '')
|
||||||
|
{
|
||||||
|
$task = 'display';
|
||||||
|
}
|
||||||
|
|
||||||
|
$class = '\\PatchTester\\Controller\\' . ucfirst(strtolower($task)) . 'Controller';
|
||||||
|
|
||||||
|
// Instantiate and execute the controller
|
||||||
|
$controller = new $class($app->input, $app);
|
||||||
|
$controller->execute();
|
||||||
|
@ -34,18 +34,14 @@
|
|||||||
<administration>
|
<administration>
|
||||||
<menu img="components/com_patchtester/assets/images/icon-16-patchtester.png">com_patchtester</menu>
|
<menu img="components/com_patchtester/assets/images/icon-16-patchtester.png">com_patchtester</menu>
|
||||||
<files folder="admin">
|
<files folder="admin">
|
||||||
|
<folder>PatchTester</folder>
|
||||||
<folder>assets</folder>
|
<folder>assets</folder>
|
||||||
<folder>backups</folder>
|
<folder>backups</folder>
|
||||||
<folder>controllers</folder>
|
|
||||||
<folder>helpers</folder>
|
<folder>helpers</folder>
|
||||||
<folder>install</folder>
|
<folder>install</folder>
|
||||||
<folder>language</folder>
|
<folder>language</folder>
|
||||||
<folder>models</folder>
|
|
||||||
<folder>tables</folder>
|
|
||||||
<folder>views</folder>
|
|
||||||
<filename>access.xml</filename>
|
<filename>access.xml</filename>
|
||||||
<filename>config.xml</filename>
|
<filename>config.xml</filename>
|
||||||
<filename>controller.php</filename>
|
|
||||||
<filename>patchtester.php</filename>
|
<filename>patchtester.php</filename>
|
||||||
</files>
|
</files>
|
||||||
</administration>
|
</administration>
|
||||||
|
@ -1,129 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* @package PatchTester
|
|
||||||
*
|
|
||||||
* @copyright Copyright (C) 2011 - 2012 Ian MacLennan, Copyright (C) 2013 - 2014 Open Source Matters, Inc. All rights reserved.
|
|
||||||
* @license GNU General Public License version 2 or later
|
|
||||||
*/
|
|
||||||
|
|
||||||
defined('_JEXEC') or die;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* View class for a list of pull requests.
|
|
||||||
*
|
|
||||||
* @package PatchTester
|
|
||||||
* @since 1.0
|
|
||||||
*/
|
|
||||||
class PatchtesterViewPulls extends JViewLegacy
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Array containing environment errors
|
|
||||||
*
|
|
||||||
* @var array
|
|
||||||
* @since 2.0
|
|
||||||
*/
|
|
||||||
protected $envErrors = array();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Array of open pull requests
|
|
||||||
*
|
|
||||||
* @var array
|
|
||||||
* @since 1.0
|
|
||||||
*/
|
|
||||||
protected $items;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* State object
|
|
||||||
*
|
|
||||||
* @var \Joomla\Registry\Registry
|
|
||||||
* @since 1.0
|
|
||||||
*/
|
|
||||||
protected $state;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Pagination object
|
|
||||||
*
|
|
||||||
* @var JPagination
|
|
||||||
* @since 2.0
|
|
||||||
*/
|
|
||||||
protected $pagination;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Execute and display a template script.
|
|
||||||
*
|
|
||||||
* @param string $tpl The name of the template file to parse; automatically searches through the template paths.
|
|
||||||
*
|
|
||||||
* @return mixed A string if successful, otherwise a Error object.
|
|
||||||
*
|
|
||||||
* @since 1.0
|
|
||||||
*/
|
|
||||||
public function display($tpl = null)
|
|
||||||
{
|
|
||||||
if (!extension_loaded('openssl'))
|
|
||||||
{
|
|
||||||
$this->envErrors[] = JText::_('COM_PATCHTESTER_REQUIREMENT_OPENSSL');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!in_array('https', stream_get_wrappers()))
|
|
||||||
{
|
|
||||||
$this->envErrors[] = JText::_('COM_PATCHTESTER_REQUIREMENT_HTTPS');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only process the data if there are no environment errors
|
|
||||||
if (!count($this->envErrors))
|
|
||||||
{
|
|
||||||
$this->state = $this->get('State');
|
|
||||||
$this->items = $this->get('Items');
|
|
||||||
$this->pagination = $this->get('Pagination');
|
|
||||||
|
|
||||||
// Check for errors.
|
|
||||||
$errors = $this->get('Errors');
|
|
||||||
|
|
||||||
if (count($errors))
|
|
||||||
{
|
|
||||||
JError::raiseError(500, implode("\n", $errors));
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->addToolbar();
|
|
||||||
|
|
||||||
return parent::display($tpl);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add the page title and toolbar.
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*
|
|
||||||
* @since 1.0
|
|
||||||
*/
|
|
||||||
protected function addToolbar()
|
|
||||||
{
|
|
||||||
JToolBarHelper::title(JText::_('COM_PATCHTESTER'), 'patchtester');
|
|
||||||
|
|
||||||
if (!count($this->envErrors))
|
|
||||||
{
|
|
||||||
JToolbarHelper::custom('pulls.fetch', 'refresh.png', 'refresh_f2.png', 'COM_PATCHTESTER_TOOLBAR_FETCH_DATA', false);
|
|
||||||
}
|
|
||||||
|
|
||||||
JToolBarHelper::preferences('com_patchtester');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns an array of fields the table can be sorted by
|
|
||||||
*
|
|
||||||
* @return array Array containing the field name to sort by as the key and display text as value
|
|
||||||
*
|
|
||||||
* @since 2.0
|
|
||||||
*/
|
|
||||||
protected function getSortFields()
|
|
||||||
{
|
|
||||||
return array(
|
|
||||||
'a.title' => JText::_('JGLOBAL_TITLE'),
|
|
||||||
'a.pull_id' => JText::_('COM_PATCHTESTER_PULL_ID'),
|
|
||||||
'applied' => JText::_('JSTATUS')
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user