Merge branch '3'

This commit is contained in:
Daniel Hensby 2016-07-25 14:51:39 +01:00
commit 1ae58bbc82
No known key found for this signature in database
GPG Key ID: B00D1E9767F0B06E
4 changed files with 189 additions and 39 deletions

View File

@ -362,7 +362,7 @@ class CMSPageHistoryController extends CMSMain {
/**
* @param int $versionID
* @param int $otherVersionID
* @return Form
* @return mixed
*/
public function CompareVersionsForm($versionID, $otherVersionID) {
if($versionID > $otherVersionID) {
@ -373,16 +373,20 @@ class CMSPageHistoryController extends CMSMain {
$fromVersion = $versionID;
}
if(!$toVersion || !$fromVersion) return false;
if(!$toVersion || !$toVersion) {
return false;
}
$id = $this->currentPageID();
$page = DataObject::get_by_id("SiteTree", $id);
if($page && !$page->canView()) {
return Security::permissionFailure($this);
}
if($page && $page->exists()) {
if(!$page->canView()) {
return Security::permissionFailure($this);
}
$record = $page->compareVersions($fromVersion, $toVersion);
$record = $page->compareVersions($fromVersion, $toVersion);
}
$fromVersionRecord = Versioned::get_version('SiteTree', $id, $fromVersion);
$toVersionRecord = Versioned::get_version('SiteTree', $id, $toVersion);
@ -395,7 +399,7 @@ class CMSPageHistoryController extends CMSMain {
user_error("Can't find version $toVersion of page $id", E_USER_ERROR);
}
if($record) {
if(isset($record)) {
$form = $this->getEditForm($id, null, null, true);
$form->setActions(new FieldList());
$form->addExtraClass('compare');
@ -418,6 +422,8 @@ class CMSPageHistoryController extends CMSMain {
return $form;
}
return false;
}
public function Breadcrumbs($unlinked = false) {

View File

@ -2448,7 +2448,10 @@ class SiteTree extends DataObject implements PermissionProvider,i18nEntityProvid
} else {
$subclasses = ClassInfo::subclassesFor($candidate);
foreach($subclasses as $subclass) {
if($subclass != "SiteTree_root") $allowedChildren[] = $subclass;
if ($subclass == 'SiteTree_root' || singleton($subclass) instanceof HiddenClass) {
continue;
}
$allowedChildren[] = $subclass;
}
}
}

106
git-sync.sh Normal file
View File

@ -0,0 +1,106 @@
#!/usr/bin/env bash
REMOTE_TO_SYNC='upstream' # default remote if none passed
QUIET=false # run in quiet mode
DO_PUSH=false # push to the branches upstream as part of the sync
ONLY_LOCAL=false # Only sync local branches (don't pull down from remote)
SKIP_FETCH=false # Skip the fetch step - really only useful if you know your up to date
Q_FLAG='' # the -q flag for CLI commands - changes to `-q` when running in quiet mode
# Our help function
function usage() {
echo -e "Syntax `basename $0` [-h] [-p] [-q] [-l] [-s] [-r remote-name]
-h Show this help
-p Push changes up to the repo
-q Quiet - minise output
-l Only sync local branches
-s Skip fetching the remote (may cause stale commits to be pushed)
-r [remote-name] Use this remote to sync with, defaults to ${REMOTE_TO_SYNC}"
}
# Heavy lifting function to coordinate the parts
function run() {
# store the local branch as we need this later to avoid a git error with forcing branch commits
local current_branch
current_branch=$(git rev-parse --abbrev-ref HEAD)
# if the remote exists, we can continue
if find_remote `git remote`; then
# Fetch the remote if required
${SKIP_FETCH} || (${QUIET} || echo "Fetching remote") && git fetch "${REMOTE_TO_SYNC}"
# populate the global BRANCHES var
get_branches_to_sync
# go through all the candidate branches and sync them if needed
for branch in ${BRANCHES[@]}; do
# If we want to sync all branches OR check a branch exists locally
#if [[ ! ${ONLY_LOCAL} ]] || branch_exists_locally "${branch}"; then
${QUIET} || echo -e "Resetting branch ${branch}"
# If the branch is currently checkedout we have to use git reset
if [[ "${current_branch}" == "${branch}" ]]; then
git reset -q --hard "${REMOTE_TO_SYNC}/${branch}"
else
# force the branch name to point to the remote ref
git branch -f --no-track "${branch}" "${REMOTE_TO_SYNC}/${branch}"
fi
# Push up to the default remote if needed
${DO_PUSH} && git push ${Q_FLAG} -f `git config --get branch."${branch}".remote` "${branch}":"${branch}"
#fi
done
return 0
else
echo "Couldn't find remote: ${REMOTE_TO_SYNC}"
return 1
fi
}
# Confirm the remote is in a list of passed remotes
function find_remote() {
local e
for e in "$@"; do
[[ "$e" == "$REMOTE_TO_SYNC" ]] && return 0;
done
return 1
}
# Get the name of all the branches on the remote
function get_branches_to_sync() {
${QUIET} || echo "getting branches"
BRANCHES=$(git branch -r | grep -e "^ *${REMOTE_TO_SYNC}\/" | sed "s/ *${REMOTE_TO_SYNC}\///")
}
# Configm the passed branch name exists locally
function branch_exists_locally() {
local e
for e in $(git branch | sed 's/\** *//'); do
[[ "$e" == "$1" ]] && return 0
done
return 1
}
# Handle the CLI params
while getopts "hr:pqls" OPTION; do
case ${OPTION} in
r ) REMOTE_TO_SYNC="$OPTARG"
;;
p ) DO_PUSH=true
;;
q ) QUIET=true
Q_FLAG='-q'
;;
l ) ONLY_LOCAL=true
;;
s ) SKIP_FETCH=true
;;
h ) usage
exit 0
;;
esac
done
run
exit $?

View File

@ -5,6 +5,7 @@ use SilverStripe\ORM\Versioning\Versioned;
use SilverStripe\ORM\DataObject;
use SilverStripe\ORM\ValidationException;
use SilverStripe\ORM\DataExtension;
use SilverStripe\ORM\HiddenClass;
use SilverStripe\Security\Member;
use SilverStripe\Security\Permission;
use SilverStripe\Security\Group;
@ -903,43 +904,73 @@ class SiteTreeTest extends SapphireTest {
);
}
public function testAllowedChildren() {
/**
* Tests that core subclasses of SiteTree are included in allowedChildren() by default, but not instances of
* HiddenClass
*/
public function testAllowedChildrenContainsCoreSubclassesButNotHiddenClass()
{
$page = new SiteTree();
$allowedChildren = $page->allowedChildren();
$this->assertContains(
'VirtualPage',
$page->allowedChildren(),
'Includes core subclasses by default'
);
'VirtualPage',
$allowedChildren,
'Includes core subclasses by default'
);
$classA = new SiteTreeTest_ClassA();
$this->assertEquals(
array('SiteTreeTest_ClassB'),
$classA->allowedChildren(),
'Direct setting of allowed children'
);
$this->assertNotContains(
'SiteTreeTest_ClassE',
$allowedChildren,
'HiddenClass instances should not be returned'
);
}
$classB = new SiteTreeTest_ClassB();
$this->assertEquals(
array('SiteTreeTest_ClassC', 'SiteTreeTest_ClassCext'),
$classB->allowedChildren(),
'Includes subclasses'
);
$classD = new SiteTreeTest_ClassD();
$this->assertEquals(
array('SiteTreeTest_ClassC'),
$classD->allowedChildren(),
'Excludes subclasses if class is prefixed by an asterisk'
);
$classC = new SiteTreeTest_ClassC();
$this->assertEquals(
array(),
$classC->allowedChildren(),
'Null setting'
);
/**
* Tests that various types of SiteTree classes will or will not be returned from the allowedChildren method
* @dataProvider allowedChildrenProvider
* @param string $className
* @param array $expected
* @param string $assertionMessage
*/
public function testAllowedChildren($className, $expected, $assertionMessage)
{
$class = new $className;
$this->assertEquals($expected, $class->allowedChildren(), $assertionMessage);
}
/**
* @return array
*/
public function allowedChildrenProvider()
{
return array(
array(
// Class name
'SiteTreeTest_ClassA',
// Expected
array('SiteTreeTest_ClassB'),
// Assertion message
'Direct setting of allowed children'
),
array(
'SiteTreeTest_ClassB',
array('SiteTreeTest_ClassC', 'SiteTreeTest_ClassCext'),
'Includes subclasses'
),
array(
'SiteTreeTest_ClassC',
array(),
'Null setting'
),
array(
'SiteTreeTest_ClassD',
array('SiteTreeTest_ClassC'),
'Excludes subclasses if class is prefixed by an asterisk'
)
);
}
public function testAllowedChildrenValidation() {
$page = new SiteTree();
$page->write();
@ -1295,6 +1326,10 @@ class SiteTreeTest_ClassD extends Page implements TestOnly {
}
}
class SiteTreeTest_ClassE extends Page implements TestOnly, HiddenClass {
}
class SiteTreeTest_ClassCext extends SiteTreeTest_ClassC implements TestOnly {
// Override SiteTreeTest_ClassC definitions
private static $allowed_children = array('SiteTreeTest_ClassB');