(merged from branches/roa. use "svn log -c <changeset> -g <module-svn-path>" for detailed commit message)

git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@60352 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
Ingo Schommer 2008-08-11 03:39:14 +00:00
parent dff25fc11c
commit 4735f91ab8
9 changed files with 103 additions and 42 deletions

View File

@ -130,9 +130,10 @@ class SOAPModelAccess extends SapphireSoapServer {
$response = Director::test( $response = Director::test(
$this->buildRestfulURL($class, $id, $relation, 'xml'), $this->buildRestfulURL($class, $id, $relation, 'xml'),
$data, array(),
null, null,
($id) ? 'PUT' : 'POST' ($id) ? 'PUT' : 'POST',
$data
); );
return ($response->isError()) ? $this->getErrorMessage($response) : $response->getBody(); return ($response->isError()) ? $this->getErrorMessage($response) : $response->getBody();
@ -154,9 +155,10 @@ class SOAPModelAccess extends SapphireSoapServer {
$response = Director::test( $response = Director::test(
$this->buildRestfulURL($class, $id, $relation, 'json'), $this->buildRestfulURL($class, $id, $relation, 'json'),
$data, array(),
null, null,
($id) ? 'PUT' : 'POST' ($id) ? 'PUT' : 'POST',
$data
); );
return ($response->isError()) ? $this->getErrorMessage($response) : $response->getBody(); return ($response->isError()) ? $this->getErrorMessage($response) : $response->getBody();
@ -216,8 +218,8 @@ class SOAPModelAccess extends SapphireSoapServer {
* @param string $password Plaintext password * @param string $password Plaintext password
*/ */
protected function authenticate($username, $password) { protected function authenticate($username, $password) {
$_SERVER['PHP_AUTH_USER'] = $username; if(is_string($username)) $_SERVER['PHP_AUTH_USER'] = $username;
$_SERVER['PHP_AUTH_PW'] = $password; if(is_string($password)) $_SERVER['PHP_AUTH_PW'] = $password;
} }
/** /**

View File

@ -82,6 +82,12 @@ class RequestHandlingData extends ViewableData {
if($action[0] == '$') $action = $params[substr($action,1)]; if($action[0] == '$') $action = $params[substr($action,1)];
if($this->checkAccessAction($action)) { if($this->checkAccessAction($action)) {
if(!$action) {
if(isset($_REQUEST['debug_request'])) Debug::message("Action not set; using default action method name 'index'");
$action = "index";
} else if(!is_string($action)) {
user_error("Non-string method name: " . var_export($action, true), E_USER_ERROR);
}
$result = $this->$action($request); $result = $this->$action($request);
} else { } else {
return $this->httpError(403, "Action '$action' isn't allowed on class $this->class"); return $this->httpError(403, "Action '$action' isn't allowed on class $this->class");

View File

@ -2417,6 +2417,7 @@ class DataObject extends ViewableData implements DataObjectInterface {
public function fieldLabels($fieldName = false) { public function fieldLabels($fieldName = false) {
$customLabels = $this->stat('field_labels'); $customLabels = $this->stat('field_labels');
$autoLabels = array(); $autoLabels = array();
if($this->databaseFields()){
foreach($this->databaseFields() as $name => $type) { foreach($this->databaseFields() as $name => $type) {
$autoLabels[$name] = FormField::name_to_label($name); $autoLabels[$name] = FormField::name_to_label($name);
} }
@ -2426,7 +2427,7 @@ class DataObject extends ViewableData implements DataObjectInterface {
return (isset($labels[$fieldName])) ? $labels[$fieldName] : FormField::name_to_label($fieldName); return (isset($labels[$fieldName])) ? $labels[$fieldName] : FormField::name_to_label($fieldName);
} else { } else {
return $labels; return $labels;
} }}
} }
/** /**

View File

@ -100,8 +100,8 @@ class HtmlEditorField extends TextareaField {
$content = preg_replace('/mce_real_src="[^"]+"/i', "", $content); $content = preg_replace('/mce_real_src="[^"]+"/i', "", $content);
$content = eregi_replace('width=([0-9]+)','width="\\1"',$content); $content = eregi_replace('(<img[^>]* )width=([0-9]+)( [^>]*>|>)','\\1width="\\2"\\3',$content);
$content = eregi_replace('height=([0-9]+)','height="\\1"',$content); $content = eregi_replace('(<img[^>]* )height=([0-9]+)( [^>]*>|>)','\\1height="\\2"\\3',$content);
$content = eregi_replace('src="([^\?]*)\?r=[0-9]+"','src="\\1"',$content); $content = eregi_replace('src="([^\?]*)\?r=[0-9]+"','src="\\1"',$content);
$content = eregi_replace('mce_src="([^\?]*)\?r=[0-9]+"','mce_src="\\1"',$content); $content = eregi_replace('mce_src="([^\?]*)\?r=[0-9]+"','mce_src="\\1"',$content);

View File

@ -221,6 +221,10 @@ class TableListField extends FormField {
Requirements::css('sapphire/css/TableListField.css'); Requirements::css('sapphire/css/TableListField.css');
} }
function index() {
return $this->FieldHolder();
}
function FieldHolder() { function FieldHolder() {
if($this->clickAction) { if($this->clickAction) {

View File

@ -85,10 +85,10 @@ class SearchContext extends Object {
*/ */
protected function applyBaseTableFields() { protected function applyBaseTableFields() {
$classes = ClassInfo::dataClassesFor($this->modelClass); $classes = ClassInfo::dataClassesFor($this->modelClass);
$fields = array(ClassInfo::baseDataClass($this->modelClass).'.*'); $fields = array("`".ClassInfo::baseDataClass($this->modelClass).'`.*');
if($this->modelClass != $classes[0]) $fields[] = $classes[0].'.*'; if($this->modelClass != $classes[0]) $fields[] = '`'.$classes[0].'`.*';
//$fields = array_keys($model->db()); //$fields = array_keys($model->db());
$fields[] = $classes[0].'.ClassName AS RecordClassName'; $fields[] = '`'.$classes[0].'`.ClassName AS RecordClassName';
return $fields; return $fields;
} }
@ -112,6 +112,7 @@ class SearchContext extends Object {
} else { } else {
$query = $model->buildSQL(); $query = $model->buildSQL();
} }
$query->select = array_merge($query->select,$fields); $query->select = array_merge($query->select,$fields);
$SQL_limit = Convert::raw2sql($limit); $SQL_limit = Convert::raw2sql($limit);
@ -119,7 +120,17 @@ class SearchContext extends Object {
$SQL_sort = (!empty($sort)) ? Convert::raw2sql($sort) : singleton($this->modelClass)->stat('default_sort'); $SQL_sort = (!empty($sort)) ? Convert::raw2sql($sort) : singleton($this->modelClass)->stat('default_sort');
$query->orderby($SQL_sort); $query->orderby($SQL_sort);
foreach($searchParams as $key => $value) {
// hack to work with $searchParems when it's an Object
$searchParamArray = array();
if (is_object($searchParams)) {
$searchParamArray = $searchParams->getVars();
} else
{
$searchParamArray = $searchParams;
}
foreach($searchParamArray as $key => $value) {
$key = str_replace('__', '.', $key); $key = str_replace('__', '.', $key);
if($filter = $this->getFilter($key)) { if($filter = $this->getFilter($key)) {
$filter->setModel($this->modelClass); $filter->setModel($this->modelClass);
@ -130,6 +141,7 @@ class SearchContext extends Object {
} }
} }
$query->connective = $this->connective; $query->connective = $this->connective;
return $query; return $query;

View File

@ -14,7 +14,20 @@ class ExactMatchMultiFilter extends SearchFilter {
public function apply(SQLQuery $query) { public function apply(SQLQuery $query) {
$query = $this->applyRelation($query); $query = $this->applyRelation($query);
// hack
// PREVIOUS $values = explode(',',$this->getValue());
$values = array();
if (is_string($this->getValue())) {
$values = explode(',',$this->getValue()); $values = explode(',',$this->getValue());
}
else {
foreach($this->getValue() as $v) {
$values[] = $v;
}
}
if(! $values) return false; if(! $values) return false;
for($i = 0; $i < count($values); $i++) { for($i = 0; $i < count($values); $i++) {
if(! is_numeric($values[$i])) { if(! is_numeric($values[$i])) {

View File

@ -48,6 +48,11 @@ class MemberAuthenticator extends Authenticator {
if($existingMember) $attempt->MemberID = $existingMember->ID; if($existingMember) $attempt->MemberID = $existingMember->ID;
$attempt->Status = 'Failure'; $attempt->Status = 'Failure';
} }
if(is_array($RAW_data['Email'])) {
user_error("Bad email passed to MemberAuthenticator::authenticate(): $RAW_data[Email]", E_USER_WARNING);
return false;
}
$attempt->Email = $RAW_data['Email']; $attempt->Email = $RAW_data['Email'];
$attempt->IP = Controller::curr()->getRequest()->getIP(); $attempt->IP = Controller::curr()->getRequest()->getIP();
$attempt->write(); $attempt->write();

View File

@ -11,9 +11,17 @@
class SoapModelAccessTest extends SapphireTest { class SoapModelAccessTest extends SapphireTest {
static $fixture_file = 'sapphire/tests/SoapModelAccessTest.yml'; static $fixture_file = 'sapphire/tests/SoapModelAccessTest.yml';
/*
public function getTestSoapConnection() {
// We can't actually test the SOAP server itself because there's not currently a way of putting it into "test mode"
return new SOAPModelAccess();
// One day, we should build this facility and then return something more like the item below:
// return new SoapClient(Director::absoluteBaseURL() . 'soap/v1/wsdl');
}
public function testApiAccess() { public function testApiAccess() {
$c = new SoapClient(Director::absoluteBaseURL() . 'soap/v1/wsdl'); $c = $this->getTestSoapConnection();
$soapResponse = $c->getXML( $soapResponse = $c->getXML(
"SoapModelAccessTest_Comment", "SoapModelAccessTest_Comment",
1, 1,
@ -22,8 +30,7 @@ class SoapModelAccessTest extends SapphireTest {
'editor@test.com', 'editor@test.com',
'editor' 'editor'
); );
var_dump($soapResponse);
die();
$responseArr = Convert::xml2array($soapResponse); $responseArr = Convert::xml2array($soapResponse);
$this->assertEquals($responseArr['ID'], 1); $this->assertEquals($responseArr['ID'], 1);
$this->assertEquals($responseArr['Name'], 'Joe'); $this->assertEquals($responseArr['Name'], 'Joe');
@ -31,56 +38,67 @@ class SoapModelAccessTest extends SapphireTest {
public function testAuthenticatedPUT() { public function testAuthenticatedPUT() {
// test wrong details // test wrong details
$c = new SoapClient(Director::absoluteBaseURL() . 'soap/v1/wsdl'); $c = $this->getTestSoapConnection();
$soapResponse = $c->getXML(
$updateXML = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<SoapModelAccessTest_Comment>
<ID>1</ID>
<Name>Jimmy</Name>
</SoapModelAccessTest_Comment>
XML;
$soapResponse = $c->putXML(
"SoapModelAccessTest_Comment", "SoapModelAccessTest_Comment",
1, 1,
null, null,
array( $updateXML,
'Name' => 'Updated Name'
),
'editor@test.com', 'editor@test.com',
'wrongpassword' 'wrongpassword'
); );
$this->assertEquals( $this->assertEquals('<error type="authentication" code="403">Forbidden</error>', $soapResponse);
$soapResponse,
'<error type="authentication" code="403">Forbidden</error>'
);
// test correct details // Check that the details weren't saved
$c = new SoapClient(Director::absoluteBaseURL() . 'soap/v1/wsdl'); $c = $this->getTestSoapConnection();
$soapResponse = $c->getXML( $soapResponse = $c->getXML("SoapModelAccessTest_Comment", 1, null, 'editor@test.com', 'editor');
$responseArr = Convert::xml2array($soapResponse);
$this->assertEquals(1, $responseArr['ID']);
$this->assertEquals('Joe', $responseArr['Name']);
// Now do an update with the right password
$soapResponse = $c->putXML(
"SoapModelAccessTest_Comment", "SoapModelAccessTest_Comment",
1, 1,
null, null,
array( $updateXML,
'Name' => 'Updated Name'
),
'editor@test.com', 'editor@test.com',
'editor' 'editor'
); );
// Check that the details were saved
$c = $this->getTestSoapConnection();
$soapResponse = $c->getXML("SoapModelAccessTest_Comment", 1, null, 'editor@test.com', 'editor');
$responseArr = Convert::xml2array($soapResponse); $responseArr = Convert::xml2array($soapResponse);
$this->assertEquals($responseArr['ID'], 1); $this->assertEquals(1, $responseArr['ID']);
$this->assertEquals($responseArr['Name'], 'Updated Name'); $this->assertEquals('Jimmy', $responseArr['Name']);
} }
public function testAuthenticatedPOST() { public function testAuthenticatedPOST() {
$c = new SoapClient(Director::absoluteBaseURL() . 'soap/v1/wsdl'); /*
$c = $this->getTestSoapConnection();
$soapResponse = $c->getXML( $soapResponse = $c->getXML(
"SoapModelAccessTest_Comment", "SoapModelAccessTest_Comment",
null, null,
null, null,
array(
'Name' => 'Created Name'
),
'editor@test.com', 'editor@test.com',
'editor' 'editor'
); );
Debug::message($soapResponse);
$responseArr = Convert::xml2array($soapResponse); $responseArr = Convert::xml2array($soapResponse);
Debug::show($responseArr);
$this->assertEquals($responseArr['Name'], 'Created Name'); $this->assertEquals($responseArr['Name'], 'Created Name');
}
*/ */
}
} }
/** /**