Skip to content

Commit 077e57c

Browse files
author
Ian MacLennan
committed
Creating component
0 parents  commit 077e57c

33 files changed

+1389
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<access component="com_patchtester">
3+
<section name="component">
4+
<action name="core.admin" title="JACTION_ADMIN" description="JACTION_ADMIN_COMPONENT_DESC" />
5+
<action name="core.manage" title="JACTION_MANAGE" description="JACTION_MANAGE_COMPONENT_DESC" />
6+
</section>
7+
</access>

administrator/components/com_patchtester/backups/index.html

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<config>
3+
<fieldset name="component"
4+
label="COM_PATCHTESTER_COMPONENT_LABEL"
5+
description="COM_PATCHTESTER_COMPONENT_DESC"
6+
>
7+
8+
<field name="org" type="text"
9+
default="joomla"
10+
description="COM_PATCHTESTER_FIELD_ORG_DESC"
11+
label="COM_PATCHTESTER_FIELD_ORG_LABEL"
12+
/>
13+
14+
<field name="repo" type="text"
15+
default="joomla-cms"
16+
description="COM_PATCHTESTER_FIELD_REPO_DESC"
17+
label="COM_PATCHTESTER_FIELD_REPO_LABEL"
18+
/>
19+
20+
</fieldset>
21+
22+
<fieldset name="permissions"
23+
description="JCONFIG_PERMISSIONS_DESC"
24+
label="JCONFIG_PERMISSIONS_LABEL"
25+
>
26+
27+
<field name="rules" type="rules"
28+
component="com_patchtester"
29+
filter="rules"
30+
validate="rules"
31+
label="JCONFIG_PERMISSIONS_LABEL"
32+
section="component" />
33+
</fieldset>
34+
</config>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
/**
3+
* @package PatchTester
4+
* @copyright Copyright (C) 2011 Ian MacLennan, Inc. All rights reserved.
5+
* @license GNU General Public License version 2 or later; see LICENSE.txt
6+
*/
7+
8+
// No direct access
9+
defined('_JEXEC') or die;
10+
11+
/**
12+
* PatchTester Controller
13+
*
14+
* @package PatchTester
15+
*/
16+
class PatchTesterController extends JController
17+
{
18+
protected $default_view = 'Pulls';
19+
20+
/**
21+
* Method to display a view.
22+
*
23+
* @param boolean $cachable If true, the view output will be cached
24+
* @param array $urlparams An array of safe url parameters and their variable types, for valid values see {@link JFilterInput::clean()}.
25+
*
26+
* @return JController This object to support chaining.
27+
* @since 1.5
28+
*/
29+
public function display($cachable = false, $urlparams = false)
30+
{
31+
parent::display();
32+
33+
return $this;
34+
}
35+
}

administrator/components/com_patchtester/controllers/index.html

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
/**
3+
* @package PatchTester
4+
* @copyright Copyright (C) 2011 Ian MacLennan, Inc. All rights reserved.
5+
* @license GNU General Public License version 2 or later; see LICENSE.txt
6+
*/
7+
8+
// No direct access
9+
defined('_JEXEC') or die;
10+
11+
jimport('joomla.application.component.controllerform');
12+
13+
/**
14+
* Pull controller class
15+
*
16+
* @package PatchTester
17+
*/
18+
class PatchtesterControllerPull extends JController
19+
{
20+
public function apply()
21+
{
22+
$model = $this->getModel('pull');
23+
if ($model->apply(JRequest::getVar('pull_id'))) {
24+
$msg = 'Patch successfully applied';
25+
} else {
26+
$msg = 'Patch did not apply';
27+
}
28+
$this->setRedirect(JRoute::_('index.php?option=com_patchtester&view=pulls', false), $msg);
29+
}
30+
31+
public function revert()
32+
{
33+
$model = $this->getModel('pull');
34+
if ($model->revert(JRequest::getVar('pull_id'))) {
35+
$msg = 'Patch successfully reverted';
36+
} else {
37+
$msg = 'Patch did not revert';
38+
}
39+
$this->setRedirect(JRoute::_('index.php?option=com_patchtester&view=pulls', false), $msg);
40+
}
41+
42+
}

administrator/components/com_patchtester/index.html

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
COM_PATCHTESTER_NOT_APPLIED="Not Applied"
2+
COM_PATCHTESTER_APPLIED="Applied"
3+
COM_PATCHTESTER_REVERT_PATCH="Revert Patch"
4+
COM_PATCHTESTER_APPLY_PATCH="Apply Patch"
5+
COM_PATCHTESTER_TEST_THIS_PATCH="Test This Patch"
6+
COM_PATCHTESTER_REPO_IS_GONE="The patch could not be applied because the repository is missing"
7+
COM_PATCHTESTER_CONFLICT="The patch could not be applied because it conflicts with a previously applied patch"
8+
COM_PATCHTESTER_COMPONENT_LABEL="Patch Tester"
9+
COM_PATCHTESTER_COMPONENT_DESC="Patch Tester Configuration Values"
10+
COM_PATCHTESTER_FIELD_ORG_DESC="Github Username"
11+
COM_PATCHTESTER_FIELD_ORG_LABEL="Name of account on Github of which to monitor pull requests"
12+
COM_PATCHTESTER_FIELD_REPO_DESC="Github Repository"
13+
COM_PATCHTESTER_FIELD_REPO_LABEL="Name of repository on Github of which to monitor pull requests"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
COM_PATCHTESTER="Patch Tester"
2+
COM_PATCHTESTER_XML_DESCRIPTION="Component for pull request management testing"
3+

administrator/components/com_patchtester/language/en-GB/index.html

Whitespace-only changes.

administrator/components/com_patchtester/language/index.html

Whitespace-only changes.

administrator/components/com_patchtester/models/index.html

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
<?php
2+
/**
3+
* @package PatchTester
4+
* @copyright Copyright (C) 2011 Ian MacLennan, Inc. All rights reserved.
5+
* @license GNU General Public License version 2 or later; see LICENSE.txt
6+
*/
7+
8+
defined('_JEXEC') or die;
9+
10+
/**
11+
* Methods supporting pull requests.
12+
*
13+
* @package PatchTester
14+
*/
15+
class PatchtesterModelPull extends JModel
16+
{
17+
18+
/**
19+
* Method to auto-populate the model state.
20+
*
21+
* Note. Calling getState in this method will result in recursion.
22+
*
23+
* @since 1.6
24+
*/
25+
protected function populateState()
26+
{
27+
// Initialise variables.
28+
$app = JFactory::getApplication('administrator');
29+
30+
// Load the parameters.
31+
$params = JComponentHelper::getParams('com_patchtester');
32+
$this->setState('params', $params);
33+
$this->setState('github_user', $params->get('org'));
34+
$this->setState('github_repo', $params->get('repo'));
35+
36+
parent::populateState();
37+
}
38+
39+
40+
public function apply($id)
41+
{
42+
jimport('joomla.client.github');
43+
jimport('joomla.client.http');
44+
45+
$table = JTable::getInstance('tests', 'PatchTesterTable');
46+
$github = new JGithub();
47+
$pull = $github->pulls->get($this->getState('github_user'), $this->getState('github_repo'), $id);
48+
$patchUrl = $pull->patch_url;
49+
50+
$http = new JHttp;
51+
52+
$patch = $http->get($patchUrl)->body;
53+
$patch = explode("\n", $patch);
54+
55+
$files = array();
56+
57+
foreach ($patch AS $line)
58+
{
59+
if (is_null($pull->head->repo)) {
60+
$this->setError(JText::_('COM_PATCHTESTER_REPO_IS_GONE'));
61+
return false;
62+
}
63+
64+
if (strpos($line, '--- a/') === 0) {
65+
$file = substr($line, 6);
66+
67+
// if the backup file already exists, we can't apply the patch
68+
if (file_exists(JPATH_COMPONENT . '/backups/' . md5($file) . '.txt')) {
69+
$this->setError(JText::_('COM_PATCHTESTER_CONFLICT'));
70+
return false;
71+
}
72+
$files[] = $file;
73+
}
74+
}
75+
76+
foreach ($files AS $file)
77+
{
78+
// we only create a backup if the file already exists
79+
if (file_exists(JPATH_ROOT . '/' . $file)) {
80+
JFile::copy(JPath::clean(JPATH_ROOT . '/' . $file), JPATH_COMPONENT . '/backups/' . md5($file) . '.txt');
81+
}
82+
83+
$url = 'https://raw.github.com/' . $pull->head->user->login . '/' . $pull->head->repo->name . '/' .
84+
$pull->head->ref . $file;
85+
$newFile = $http->get($url);
86+
JFile::write(JPath::clean(JPATH_ROOT . '/' . $file), $newFile->body);
87+
88+
}
89+
$table->pull_id = $pull->number;
90+
$table->data = json_encode($files);
91+
$table->patched_by = JFactory::getUser()->id;
92+
$table->applied = 1;
93+
$version = new JVersion;
94+
$table->applied_version = $version->getShortVersion();
95+
$result = $table->store();
96+
97+
if ($result) {
98+
return true;
99+
} else {
100+
return false;
101+
}
102+
}
103+
104+
public function revert($id)
105+
{
106+
$table = JTable::getInstance('tests', 'PatchTesterTable');
107+
108+
$table->load($id);
109+
110+
// we don't want to restore files from an older version
111+
$version = new JVersion;
112+
if ($table->applied_version != $version->getShortVersion()) {
113+
$table->applied = 0;
114+
$table->applied_version = '';
115+
$table->store();
116+
return true;
117+
}
118+
119+
$files = json_decode($table->data);
120+
121+
foreach ($files AS $file) {
122+
JFile::copy(JPATH_COMPONENT . '/backups/' . md5($file) . '.txt', JPATH_ROOT . '/' . $file);
123+
JFile::delete(JPATH_COMPONENT . '/backups/' . md5($file) . '.txt');
124+
}
125+
126+
$table->applied_version = '';
127+
$table->applied = 0;
128+
$table->store();
129+
130+
return true;
131+
}
132+
133+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
<?php
2+
/**
3+
* @package PatchTester
4+
* @copyright Copyright (C) 2011 Ian MacLennan, Inc. All rights reserved.
5+
* @license GNU General Public License version 2 or later; see LICENSE.txt
6+
*/
7+
8+
defined('_JEXEC') or die;
9+
10+
jimport('joomla.application.component.modellist');
11+
12+
/**
13+
* Methods supporting a list of pull request.
14+
*
15+
* @package PatchTester
16+
*/
17+
class PatchtesterModelPulls extends JModelList
18+
{
19+
20+
/**
21+
* Constructor.
22+
*
23+
* @param array An optional associative array of configuration settings.
24+
* @see JController
25+
* @since 1.6
26+
*/
27+
public function __construct($config = array())
28+
{
29+
if (empty($config['filter_fields'])) {
30+
$config['filter_fields'] = array(
31+
'id', 'id',
32+
'title', 'title',
33+
'updated_at', 'updated_at',
34+
'user', 'user'
35+
);
36+
}
37+
38+
parent::__construct($config);
39+
}
40+
41+
42+
/**
43+
* Method to auto-populate the model state.
44+
*
45+
* Note. Calling getState in this method will result in recursion.
46+
*
47+
* @since 1.6
48+
*/
49+
protected function populateState($ordering = null, $direction = null)
50+
{
51+
// Initialise variables.
52+
$app = JFactory::getApplication('administrator');
53+
54+
// Load the parameters.
55+
$params = JComponentHelper::getParams('com_patchtester');
56+
57+
$this->setState('params', $params);
58+
$this->setState('github_user', $params->get('org'));
59+
$this->setState('github_repo', $params->get('repo'));
60+
// List state information.
61+
parent::populateState('title', 'asc');
62+
}
63+
64+
/**
65+
* Method to get a store id based on model configuration state.
66+
*
67+
* This is necessary because the model is used by the component and
68+
* different modules that might need different sets of data or different
69+
* ordering requirements.
70+
*
71+
* @param string $id A prefix for the store id.
72+
* @return string A store id.
73+
* @since 1.6
74+
*/
75+
protected function getStoreId($id = '')
76+
{
77+
return parent::getStoreId($id);
78+
}
79+
80+
public function getAppliedPatches()
81+
{
82+
$query = $this->_db->getQuery(true);
83+
$query->select('*');
84+
$query->from('#__tests');
85+
$query->where('applied = 1');
86+
87+
$this->_db->setQuery($query);
88+
$tests = $this->_db->loadObjectList('pull_id');
89+
return $tests;
90+
}
91+
92+
public function getItems()
93+
{
94+
jimport('joomla.client.github');
95+
96+
if ($this->getState('github_user') == '' || $this->getState('github_repo') == '') {
97+
return array();
98+
}
99+
100+
$github = new JGithub();
101+
$pulls = $github->pulls->getAll($this->getState('github_user'), $this->getState('github_repo'));
102+
usort($pulls, array($this, 'sortItems'));
103+
return $pulls;
104+
}
105+
106+
public function sortItems($a, $b)
107+
{
108+
return strcasecmp($a->title, $b->title);
109+
}
110+
}

0 commit comments

Comments
 (0)