Skip to content
Browse files

Merge remote-tracking branch 'origin/3.0' into 3.1

Conflicts:
	admin/javascript/LeftAndMain.AddForm.js
	control/Director.php
	control/HTTPResponse.php
	dev/Profiler.php
	email/Mailer.php
	forms/ComplexTableField.php
	forms/ManyManyComplexTableField.php
	forms/SimpleImageField.php
	forms/TableField.php
	forms/TableListField.php
	javascript/ComplexTableField.js
	javascript/ImageFormAction.js
	javascript/TableField.js
	javascript/TableListField.js
	security/Member.php
	tests/behat/features/bootstrap/SilverStripe/Framework/Test/Behaviour/CmsUiContext.php
	tests/forms/TableListFieldTest.php
  • Loading branch information...
2 parents 4b38571 + 8fdea7a commit f03ad7b0ddc082f81af86f4a6e788b2311eb51df @chillu chillu committed Dec 12, 2012
View
38 control/Director.php
@@ -141,18 +141,18 @@ public static function direct($url, DataModel $model) {
$res = Injector::inst()->get('RequestProcessor')->postRequest($req, $response, $model);
if ($res !== false) {
- // Set content length (according to RFC2616)
- if(
- !headers_sent()
- && $response->getBody()
- && $req->httpMethod() != 'HEAD'
- && $response->getStatusCode() >= 200
- && !in_array($response->getStatusCode(), array(204, 304))
- ) {
- $response->fixContentLength();
- }
+ // Set content length (according to RFC2616)
+ if(
+ !headers_sent()
+ && $response->getBody()
+ && $req->httpMethod() != 'HEAD'
+ && $response->getStatusCode() >= 200
+ && !in_array($response->getStatusCode(), array(204, 304))
+ ) {
+ $response->fixContentLength();
+ }
- $response->output();
+ $response->output();
} else {
// @TODO Proper response here.
throw new SS_HTTPResponse_Exception("Invalid response");
@@ -308,7 +308,7 @@ protected static function handleRequest(SS_HTTPRequest $request, Session $sessio
}
}
}
-
+
/**
* Set url parameters (should only be called internally by RequestHandler->handleRequest()).
*
@@ -454,7 +454,7 @@ public static function makeRelative($url) {
// Allow for the accidental inclusion whitespace and // in the URL
$url = trim(preg_replace('#([^:])//#', '\\1/', $url));
- $base1 = self::absoluteBaseURL();
+ $base1 = self::absoluteBaseURL();
$baseDomain = substr($base1, strlen(self::protocol()));
// Only bother comparing the URL to the absolute version if $url looks like a URL.
@@ -470,10 +470,10 @@ public static function makeRelative($url) {
return substr($url,strlen($base1));
}
else if(substr($base1,-1)=="/" && $url == substr($base1,0,-1)) {
- // Convert http://www.mydomain.com/mysitedir to ''
+ // Convert http://www.mydomain.com/mysitedir to ''
return "";
- }
-
+ }
+
if(substr($urlWithoutProtocol,0,strlen($baseDomain)) == $baseDomain) {
return substr($urlWithoutProtocol,strlen($baseDomain));
}
@@ -488,7 +488,7 @@ public static function makeRelative($url) {
if(substr($url,0,strlen($base3)) == $base3) {
return substr($url,strlen($base3));
}
-
+
// Test for relative base url, e.g mywebsite/ if the full url is localhost/myswebsite
if(substr($url,0,strlen($baseDomain)) == $baseDomain) {
return substr($url, strlen($baseDomain));
@@ -539,8 +539,8 @@ public static function is_absolute_url($url) {
// Base check for existence of a host on a compliant URL
parse_url($url, PHP_URL_HOST)
// Check for more than one leading slash without a protocol.
- // While not a RFC compliant absolute URL, it is completed to a valid URL by some browsers,
- // and hence a potential security risk. Single leading slashes are not an issue though.
+ // While not a RFC compliant absolute URL, it is completed to a valid URL by some browsers,
+ // and hence a potential security risk. Single leading slashes are not an issue though.
|| preg_match('/\s*[\/]{2,}/', $url)
|| (
// If a colon is found, check if it's part of a valid scheme definition
View
16 control/HTTPResponse.php
@@ -123,7 +123,7 @@ public function setStatusCode($code, $description = null) {
* The text to be given alongside the status code ("reason phrase").
* Caution: Will be overwritten by {@link setStatusCode()}.
*
- * @param String $description
+ * @param String $description
* @return SS_HTTPRequest $this
*/
public function setStatusDescription($description) {
@@ -153,15 +153,15 @@ public function getStatusDescription() {
public function isError() {
return $this->statusCode && ($this->statusCode < 200 || $this->statusCode > 399);
}
-
+
/**
* @param string $body
* @return SS_HTTPRequest $this
*/
public function setBody($body) {
$this->body = $body;
}
-
+
/**
* @return null|string
*/
@@ -173,7 +173,7 @@ public function getBody() {
* Add a HTTP header to the response, replacing any header of the same name.
*
* @param string $header Example: "Content-Type"
- * @param string $value Example: "text/xml"
+ * @param string $value Example: "text/xml"
* @return SS_HTTPRequest $this
*/
public function addHeader($header, $value) {
@@ -189,9 +189,9 @@ public function addHeader($header, $value) {
*/
public function getHeader($header) {
if(isset($this->headers[$header]))
- return $this->headers[$header];
- return null;
- }
+ return $this->headers[$header];
+ return null;
+ }
/**
* @return array
@@ -211,7 +211,7 @@ public function removeHeader($header) {
if(isset($this->headers[$header])) unset($this->headers[$header]);
return $this;
}
-
+
/**
* @param string $dest
* @param int $code
View
35 control/injector/Injector.php
@@ -362,6 +362,7 @@ public function load($config = array()) {
// EXCEPT when there's already an existing instance at this id.
// if so, we need to instantiate and replace immediately
if (isset($this->serviceCache[$id])) {
+ $this->updateSpecConstructor($spec);
$this->instantiate($spec, $id);
}
}
@@ -403,6 +404,20 @@ public function updateSpec($id, $property, $value, $append = true) {
}
}
}
+
+ /**
+ * Update a class specification to convert constructor configuration information if needed
+ *
+ * We do this as a separate process to avoid unneeded calls to convertServiceProperty
+ *
+ * @param array $spec
+ * The class specification to update
+ */
+ protected function updateSpecConstructor(&$spec) {
+ if (isset($spec['constructor'])) {
+ $spec['constructor'] = $this->convertServiceProperty($spec['constructor']);
+ }
+ }
/**
* Recursively convert a value into its proper representation with service references
@@ -468,7 +483,7 @@ protected function instantiate($spec, $id=null, $type = null) {
$constructorParams = $spec['constructor'];
}
- $object = $this->objectCreator->create($this, $class, $constructorParams);
+ $object = $this->objectCreator->create($class, $constructorParams);
// figure out if we have a specific id set or not. In some cases, we might be instantiating objects
// that we don't manage directly; we don't want to store these in the service cache below
@@ -730,15 +745,22 @@ public function get($name, $asSingleton = true, $constructorArgs = null) {
// we don't want to return the singleton version of it.
$spec = $this->specs[$serviceName];
$type = isset($spec['type']) ? $spec['type'] : null;
-
+
// if we're explicitly a prototype OR we're not wanting a singleton
if (($type && $type == 'prototype') || !$asSingleton) {
if ($spec && $constructorArgs) {
$spec['constructor'] = $constructorArgs;
+ } else {
+ // convert any _configured_ constructor args.
+ // we don't call this for get() calls where someone passes in
+ // constructor args, otherwise we end up calling convertServiceParams
+ // way too often
+ $this->updateSpecConstructor($spec);
}
return $this->instantiate($spec, $serviceName, !$type ? 'prototype' : $type);
} else {
if (!isset($this->serviceCache[$serviceName])) {
+ $this->updateSpecConstructor($spec);
$this->instantiate($spec, $serviceName);
}
return $this->serviceCache[$serviceName];
@@ -750,6 +772,7 @@ public function get($name, $asSingleton = true, $constructorArgs = null) {
$this->load(array($name => $config));
if (isset($this->specs[$name])) {
$spec = $this->specs[$name];
+ $this->updateSpecConstructor($spec);
return $this->instantiate($spec, $name);
}
}
@@ -816,10 +839,10 @@ class InjectionCreator {
* @param array $params
* An array of parameters to be passed to the constructor
*/
- public function create(Injector $injector, $class, $params = array()) {
+ public function create($class, $params = array()) {
$reflector = new ReflectionClass($class);
if (count($params)) {
- return $reflector->newInstanceArgs($injector->convertServiceProperty($params));
+ return $reflector->newInstanceArgs($params);
}
return $reflector->newInstance();
}
@@ -833,10 +856,10 @@ class SilverStripeInjectionCreator {
* @param array $params
* An array of parameters to be passed to the constructor
*/
- public function create(Injector $injector, $class, $params = array()) {
+ public function create($class, $params = array()) {
$class = Object::getCustomClass($class);
$reflector = new ReflectionClass($class);
- return $reflector->newInstanceArgs($injector->convertServiceProperty($params));
+ return $reflector->newInstanceArgs($params);
}
}
View
2 dev/Profiler.php
@@ -9,7 +9,7 @@
/**
* Execution time profiler.
- *
+ *
* @deprecated 3.1 The Profiler class is deprecated, use third party tools like XHProf instead
*
* @package framework
View
428 email/Mailer.php
@@ -26,8 +26,8 @@ public function sendPlain($to, $from, $subject, $plainContent, $attachedFiles =
if ($customheaders && is_array($customheaders) == false) {
echo "htmlEmail($to, $from, $subject, ...) could not send mail: improper \$customheaders passed:<BR>";
dieprintr($customheaders);
- }
-
+ }
+
// If the subject line contains extended characters, we must encode it
$subject = Convert::xml2raw($subject);
$subject = "=?UTF-8?B?" . base64_encode($subject) . "?=";
@@ -52,9 +52,9 @@ public function sendPlain($to, $from, $subject, $plainContent, $attachedFiles =
$messageParts[] = $this->encodeFileForEmail($file['tmp_name'], $file['name']);
} else {
$messageParts[] = $this->encodeFileForEmail($file);
- }
- }
-
+ }
+}
+
// We further wrap all of this into another multipart block
list($fullBody, $headers) = $this->encodeMultipart($messageParts, "multipart/mixed");
@@ -104,268 +104,268 @@ public function sendPlain($to, $from, $subject, $plainContent, $attachedFiles =
}
/**
- * Sends an email as a both HTML and plaintext
+ * Sends an email as a both HTML and plaintext
*
- * $attachedFiles should be an array of file names
- * - if you pass the entire $_FILES entry, the user-uploaded filename will be preserved
- * use $plainContent to override default plain-content generation
- *
- * @return bool
- */
+ * $attachedFiles should be an array of file names
+ * - if you pass the entire $_FILES entry, the user-uploaded filename will be preserved
+ * use $plainContent to override default plain-content generation
+ *
+ * @return bool
+ */
public function sendHTML($to, $from, $subject, $htmlContent, $attachedFiles = false, $customheaders = false,
$plainContent = false) {
- if ($customheaders && is_array($customheaders) == false) {
- echo "htmlEmail($to, $from, $subject, ...) could not send mail: improper \$customheaders passed:<BR>";
- dieprintr($customheaders);
- }
+ if ($customheaders && is_array($customheaders) == false) {
+ echo "htmlEmail($to, $from, $subject, ...) could not send mail: improper \$customheaders passed:<BR>";
+ dieprintr($customheaders);
+ }
-
- $bodyIsUnicode = (strpos($htmlContent,"&#") !== false);
- $plainEncoding = "";
-
- // We generate plaintext content by default, but you can pass custom stuff
- $plainEncoding = '';
- if(!$plainContent) {
- $plainContent = Convert::xml2raw($htmlContent);
- if(isset($bodyIsUnicode) && $bodyIsUnicode) $plainEncoding = "base64";
- }
+
+ $bodyIsUnicode = (strpos($htmlContent,"&#") !== false);
+ $plainEncoding = "";
+
+ // We generate plaintext content by default, but you can pass custom stuff
+ $plainEncoding = '';
+ if(!$plainContent) {
+ $plainContent = Convert::xml2raw($htmlContent);
+ if(isset($bodyIsUnicode) && $bodyIsUnicode) $plainEncoding = "base64";
+ }
- // If the subject line contains extended characters, we must encode the
- $subject = Convert::xml2raw($subject);
- $subject = "=?UTF-8?B?" . base64_encode($subject) . "?=";
+ // If the subject line contains extended characters, we must encode the
+ $subject = Convert::xml2raw($subject);
+ $subject = "=?UTF-8?B?" . base64_encode($subject) . "?=";
- // Make the plain text part
- $headers["Content-Type"] = "text/plain; charset=utf-8";
- $headers["Content-Transfer-Encoding"] = $plainEncoding ? $plainEncoding : "quoted-printable";
+ // Make the plain text part
+ $headers["Content-Type"] = "text/plain; charset=utf-8";
+ $headers["Content-Transfer-Encoding"] = $plainEncoding ? $plainEncoding : "quoted-printable";
$plainPart = $this->processHeaders($headers, ($plainEncoding == "base64")
- ? chunk_split(base64_encode($plainContent),60)
+ ? chunk_split(base64_encode($plainContent),60)
: wordwrap($this->QuotedPrintable_encode($plainContent),75));
- // Make the HTML part
- $headers["Content-Type"] = "text/html; charset=utf-8";
-
-
- // Add basic wrapper tags if the body tag hasn't been given
- if(stripos($htmlContent, '<body') === false) {
- $htmlContent =
- "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\n" .
- "<HTML><HEAD>\n" .
- "<META http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n" .
- "<STYLE type=\"text/css\"></STYLE>\n\n".
- "</HEAD>\n" .
- "<BODY bgColor=\"#ffffff\">\n" .
- $htmlContent .
- "\n</BODY>\n" .
- "</HTML>";
- }
+ // Make the HTML part
+ $headers["Content-Type"] = "text/html; charset=utf-8";
+
+
+ // Add basic wrapper tags if the body tag hasn't been given
+ if(stripos($htmlContent, '<body') === false) {
+ $htmlContent =
+ "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\n" .
+ "<HTML><HEAD>\n" .
+ "<META http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n" .
+ "<STYLE type=\"text/css\"></STYLE>\n\n".
+ "</HEAD>\n" .
+ "<BODY bgColor=\"#ffffff\">\n" .
+ $htmlContent .
+ "\n</BODY>\n" .
+ "</HTML>";
+ }
$headers["Content-Transfer-Encoding"] = "quoted-printable";
$htmlPart = $this->processHeaders($headers, wordwrap($this->QuotedPrintable_encode($htmlContent),75));
-
+
list($messageBody, $messageHeaders) = $this->encodeMultipart(
array($plainPart,$htmlPart),
"multipart/alternative"
);
- // Messages with attachments are handled differently
- if($attachedFiles && is_array($attachedFiles)) {
-
- // The first part is the message itself
+ // Messages with attachments are handled differently
+ if($attachedFiles && is_array($attachedFiles)) {
+
+ // The first part is the message itself
$fullMessage = $this->processHeaders($messageHeaders, $messageBody);
- $messageParts = array($fullMessage);
+ $messageParts = array($fullMessage);
- // Include any specified attachments as additional parts
- foreach($attachedFiles as $file) {
- if(isset($file['tmp_name']) && isset($file['name'])) {
+ // Include any specified attachments as additional parts
+ foreach($attachedFiles as $file) {
+ if(isset($file['tmp_name']) && isset($file['name'])) {
$messageParts[] = $this->encodeFileForEmail($file['tmp_name'], $file['name']);
- } else {
+ } else {
$messageParts[] = $this->encodeFileForEmail($file);
- }
}
-
- // We further wrap all of this into another multipart block
+ }
+
+ // We further wrap all of this into another multipart block
list($fullBody, $headers) = $this->encodeMultipart($messageParts, "multipart/mixed");
- // Messages without attachments do not require such treatment
- } else {
- $headers = $messageHeaders;
- $fullBody = $messageBody;
- }
+ // Messages without attachments do not require such treatment
+ } else {
+ $headers = $messageHeaders;
+ $fullBody = $messageBody;
+ }
- // Email headers
+ // Email headers
$headers["From"] = $this->validEmailAddr($from);
- // Messages with the X-SilverStripeMessageID header can be tracked
- if(isset($customheaders["X-SilverStripeMessageID"]) && defined('BOUNCE_EMAIL')) {
- $bounceAddress = BOUNCE_EMAIL;
- } else {
- $bounceAddress = $from;
- }
+ // Messages with the X-SilverStripeMessageID header can be tracked
+ if(isset($customheaders["X-SilverStripeMessageID"]) && defined('BOUNCE_EMAIL')) {
+ $bounceAddress = BOUNCE_EMAIL;
+ } else {
+ $bounceAddress = $from;
+ }
- // Strip the human name from the bounce address
- if(preg_match('/^([^<>]*)<([^<>]+)> *$/', $bounceAddress, $parts)) $bounceAddress = $parts[2];
+ // Strip the human name from the bounce address
+ if(preg_match('/^([^<>]*)<([^<>]+)> *$/', $bounceAddress, $parts)) $bounceAddress = $parts[2];
- // $headers["Sender"] = $from;
- $headers["X-Mailer"] = X_MAILER;
- if (!isset($customheaders["X-Priority"])) $headers["X-Priority"] = 3;
-
- $headers = array_merge((array)$headers, (array)$customheaders);
+ // $headers["Sender"] = $from;
+ $headers["X-Mailer"] = X_MAILER;
+ if (!isset($customheaders["X-Priority"])) $headers["X-Priority"] = 3;
+
+ $headers = array_merge((array)$headers, (array)$customheaders);
- // the carbon copy header has to be 'Cc', not 'CC' or 'cc' -- ensure this.
- if (isset($headers['CC'])) { $headers['Cc'] = $headers['CC']; unset($headers['CC']); }
- if (isset($headers['cc'])) { $headers['Cc'] = $headers['cc']; unset($headers['cc']); }
-
- // the carbon copy header has to be 'Bcc', not 'BCC' or 'bcc' -- ensure this.
- if (isset($headers['BCC'])) {$headers['Bcc']=$headers['BCC']; unset($headers['BCC']); }
- if (isset($headers['bcc'])) {$headers['Bcc']=$headers['bcc']; unset($headers['bcc']); }
-
+ // the carbon copy header has to be 'Cc', not 'CC' or 'cc' -- ensure this.
+ if (isset($headers['CC'])) { $headers['Cc'] = $headers['CC']; unset($headers['CC']); }
+ if (isset($headers['cc'])) { $headers['Cc'] = $headers['cc']; unset($headers['cc']); }
+
+ // the carbon copy header has to be 'Bcc', not 'BCC' or 'bcc' -- ensure this.
+ if (isset($headers['BCC'])) {$headers['Bcc']=$headers['BCC']; unset($headers['BCC']); }
+ if (isset($headers['bcc'])) {$headers['Bcc']=$headers['bcc']; unset($headers['bcc']); }
- // Send the email
+
+ // Send the email
$headers = $this->processHeaders($headers);
$to = $this->validEmailAddr($to);
-
- // Try it without the -f option if it fails
- if(!($result = @mail($to, $subject, $fullBody, $headers, "-f$bounceAddress"))) {
- $result = mail($to, $subject, $fullBody, $headers);
- }
-
- return $result;
+
+ // Try it without the -f option if it fails
+ if(!($result = @mail($to, $subject, $fullBody, $headers, "-f$bounceAddress"))) {
+ $result = mail($to, $subject, $fullBody, $headers);
}
+
+ return $result;
+}
/**
* @todo Make visibility protected in 3.2
- */
- function encodeMultipart($parts, $contentType, $headers = false) {
- $separator = "----=_NextPart_" . preg_replace('/[^0-9]/', '', rand() * 10000000000);
-
- $headers["MIME-Version"] = "1.0";
- $headers["Content-Type"] = "$contentType; boundary=\"$separator\"";
- $headers["Content-Transfer-Encoding"] = "7bit";
-
- if($contentType == "multipart/alternative") {
- // $baseMessage = "This is an encoded HTML message. There are two parts: a plain text and an HTML message,
- // open whatever suits you better.";
- $baseMessage = "\nThis is a multi-part message in MIME format.";
- } else {
- // $baseMessage = "This is a message containing attachments. The e-mail body is contained in the first
- // attachment";
- $baseMessage = "\nThis is a multi-part message in MIME format.";
- }
+ */
+function encodeMultipart($parts, $contentType, $headers = false) {
+ $separator = "----=_NextPart_" . preg_replace('/[^0-9]/', '', rand() * 10000000000);
+
+ $headers["MIME-Version"] = "1.0";
+ $headers["Content-Type"] = "$contentType; boundary=\"$separator\"";
+ $headers["Content-Transfer-Encoding"] = "7bit";
+
+ if($contentType == "multipart/alternative") {
+ // $baseMessage = "This is an encoded HTML message. There are two parts: a plain text and an HTML message,
+ // open whatever suits you better.";
+ $baseMessage = "\nThis is a multi-part message in MIME format.";
+ } else {
+ // $baseMessage = "This is a message containing attachments. The e-mail body is contained in the first
+ // attachment";
+ $baseMessage = "\nThis is a multi-part message in MIME format.";
+ }
- $separator = "\n--$separator\n";
- $body = "$baseMessage\n" .
- $separator . implode("\n".$separator, $parts) . "\n" . trim($separator) . "--";
+ $separator = "\n--$separator\n";
+ $body = "$baseMessage\n" .
+ $separator . implode("\n".$separator, $parts) . "\n" . trim($separator) . "--";
- return array($body, $headers);
- }
+ return array($body, $headers);
+}
/**
* @todo Make visibility protected in 3.2
- */
- function processHeaders($headers, $body = false) {
- $res = '';
- if(is_array($headers)) while(list($k, $v) = each($headers))
- $res .= "$k: $v\n";
- if($body) $res .= "\n$body";
- return $res;
- }
+ */
+function processHeaders($headers, $body = false) {
+ $res = '';
+ if(is_array($headers)) while(list($k, $v) = each($headers))
+ $res .= "$k: $v\n";
+ if($body) $res .= "\n$body";
+ return $res;
+}
- /**
- * Encode the contents of a file for emailing, including headers
- *
- * $file can be an array, in which case it expects these members:
- * 'filename' - the filename of the file
- * 'contents' - the raw binary contents of the file as a string
- * and can optionally include these members:
- * 'mimetype' - the mimetype of the file (calculated from filename if missing)
- * 'contentLocation' - the 'Content-Location' header value for the file
- *
- * $file can also be a string, in which case it is assumed to be the filename
- *
- * h5. contentLocation
- *
+/**
+ * Encode the contents of a file for emailing, including headers
+ *
+ * $file can be an array, in which case it expects these members:
+ * 'filename' - the filename of the file
+ * 'contents' - the raw binary contents of the file as a string
+ * and can optionally include these members:
+ * 'mimetype' - the mimetype of the file (calculated from filename if missing)
+ * 'contentLocation' - the 'Content-Location' header value for the file
+ *
+ * $file can also be a string, in which case it is assumed to be the filename
+ *
+ * h5. contentLocation
+ *
* Content Location is one of the two methods allowed for embedding images into an html email.
* It's also the simplest, and best supported.
- *
- * Assume we have an email with this in the body:
- *
- * <img src="http://example.com/image.gif" />
- *
+ *
+ * Assume we have an email with this in the body:
+ *
+ * <img src="http://example.com/image.gif" />
+ *
* To display the image, an email viewer would have to download the image from the web every time
* it is displayed. Due to privacy issues, most viewers will not display any images unless
* the user clicks 'Show images in this email'. Not optimal.
- *
+ *
* However, we can also include a copy of this image as an attached file in the email.
* By giving it a contentLocation of "http://example.com/image.gif" most email viewers
* will use this attached copy instead of downloading it. Better,
- * most viewers will show it without a 'Show images in this email' conformation.
- *
- * Here is an example of passing this information through Email.php:
- *
- * $email = new Email();
- * $email->attachments[] = array(
- * 'filename' => BASE_PATH . "/themes/mytheme/images/header.gif",
- * 'contents' => file_get_contents(BASE_PATH . "/themes/mytheme/images/header.gif"),
- * 'mimetype' => 'image/gif',
- * 'contentLocation' => Director::absoluteBaseURL() . "/themes/mytheme/images/header.gif"
- * );
- *
+ * most viewers will show it without a 'Show images in this email' conformation.
+ *
+ * Here is an example of passing this information through Email.php:
+ *
+ * $email = new Email();
+ * $email->attachments[] = array(
+ * 'filename' => BASE_PATH . "/themes/mytheme/images/header.gif",
+ * 'contents' => file_get_contents(BASE_PATH . "/themes/mytheme/images/header.gif"),
+ * 'mimetype' => 'image/gif',
+ * 'contentLocation' => Director::absoluteBaseURL() . "/themes/mytheme/images/header.gif"
+ * );
+ *
* @todo Make visibility protected in 3.2
- */
- function encodeFileForEmail($file, $destFileName = false, $disposition = NULL, $extraHeaders = "") {
- if(!$file) {
- user_error("encodeFileForEmail: not passed a filename and/or data", E_USER_WARNING);
- return;
- }
-
- if (is_string($file)) {
- $file = array('filename' => $file);
- $fh = fopen($file['filename'], "rb");
- if ($fh) {
- while(!feof($fh)) $file['contents'] .= fread($fh, 10000);
- fclose($fh);
- }
+ */
+function encodeFileForEmail($file, $destFileName = false, $disposition = NULL, $extraHeaders = "") {
+ if(!$file) {
+ user_error("encodeFileForEmail: not passed a filename and/or data", E_USER_WARNING);
+ return;
+ }
+
+ if (is_string($file)) {
+ $file = array('filename' => $file);
+ $fh = fopen($file['filename'], "rb");
+ if ($fh) {
+ while(!feof($fh)) $file['contents'] .= fread($fh, 10000);
+ fclose($fh);
}
+ }
- // Build headers, including content type
- if(!$destFileName) $base = basename($file['filename']);
- else $base = $destFileName;
+ // Build headers, including content type
+ if(!$destFileName) $base = basename($file['filename']);
+ else $base = $destFileName;
- $mimeType = $file['mimetype'] ? $file['mimetype'] : HTTP::get_mime_type($file['filename']);
- if(!$mimeType) $mimeType = "application/unknown";
- if (empty($disposition)) $disposition = isset($file['contentLocation']) ? 'inline' : 'attachment';
-
- // Encode for emailing
- if (substr($file['mimetype'], 0, 4) != 'text') {
- $encoding = "base64";
- $file['contents'] = chunk_split(base64_encode($file['contents']));
- } else {
- // This mime type is needed, otherwise some clients will show it as an inline attachment
- $mimeType = 'application/octet-stream';
- $encoding = "quoted-printable";
+ $mimeType = $file['mimetype'] ? $file['mimetype'] : HTTP::get_mime_type($file['filename']);
+ if(!$mimeType) $mimeType = "application/unknown";
+ if (empty($disposition)) $disposition = isset($file['contentLocation']) ? 'inline' : 'attachment';
+
+ // Encode for emailing
+ if (substr($file['mimetype'], 0, 4) != 'text') {
+ $encoding = "base64";
+ $file['contents'] = chunk_split(base64_encode($file['contents']));
+ } else {
+ // This mime type is needed, otherwise some clients will show it as an inline attachment
+ $mimeType = 'application/octet-stream';
+ $encoding = "quoted-printable";
$file['contents'] = $this->QuotedPrintable_encode($file['contents']);
- }
+ }
- $headers = "Content-type: $mimeType;\n\tname=\"$base\"\n".
- "Content-Transfer-Encoding: $encoding\n".
- "Content-Disposition: $disposition;\n\tfilename=\"$base\"\n" ;
-
- if ( isset($file['contentLocation']) ) $headers .= 'Content-Location: ' . $file['contentLocation'] . "\n" ;
-
- $headers .= $extraHeaders . "\n";
+ $headers = "Content-type: $mimeType;\n\tname=\"$base\"\n".
+ "Content-Transfer-Encoding: $encoding\n".
+ "Content-Disposition: $disposition;\n\tfilename=\"$base\"\n";
+
+ if ( isset($file['contentLocation']) ) $headers .= 'Content-Location: ' . $file['contentLocation'] . "\n" ;
+
+ $headers .= $extraHeaders . "\n";
- // Return completed packet
- return $headers . $file['contents'];
- }
+ // Return completed packet
+ return $headers . $file['contents'];
+}
/**
* @todo Make visibility protected in 3.2
*/
- function QuotedPrintable_encode($quotprint) {
+function QuotedPrintable_encode($quotprint) {
$quotprint = (string)str_replace('\r\n',chr(13).chr(10),$quotprint);
$quotprint = (string)str_replace('\n', chr(13).chr(10),$quotprint);
$quotprint = (string)preg_replace("~([\x01-\x1F\x3D\x7F-\xFF])~e", "sprintf('=%02X', ord('\\1'))", $quotprint);
@@ -375,25 +375,25 @@ function QuotedPrintable_encode($quotprint) {
$quotprint = (string)str_replace('=0D',"\n",$quotprint);
$quotprint = (string)str_replace('=0A',"\n",$quotprint);
return (string) $quotprint;
- }
+}
/**
* @todo Make visibility protected in 3.2
*/
- function validEmailAddr($emailAddress) {
- $emailAddress = trim($emailAddress);
- $angBrack = strpos($emailAddress, '<');
-
- if($angBrack === 0) {
- $emailAddress = substr($emailAddress, 1, strpos($emailAddress,'>')-1);
-
- } else if($angBrack) {
- $emailAddress = str_replace('@', '', substr($emailAddress, 0, $angBrack))
- .substr($emailAddress, $angBrack);
- }
+function validEmailAddr($emailAddress) {
+ $emailAddress = trim($emailAddress);
+ $angBrack = strpos($emailAddress, '<');
+
+ if($angBrack === 0) {
+ $emailAddress = substr($emailAddress, 1, strpos($emailAddress,'>')-1);
- return $emailAddress;
+ } else if($angBrack) {
+ $emailAddress = str_replace('@', '', substr($emailAddress, 0, $angBrack))
+ .substr($emailAddress, $angBrack);
}
+
+ return $emailAddress;
+}
}
/**
View
18 tests/behat/features/bootstrap/SilverStripe/Framework/Test/Behaviour/CmsUiContext.php
@@ -339,9 +339,9 @@ public function theIFillInTheDropdownWith($field, $value)
}
assertGreaterThan(0, count($formFields), sprintf(
- 'Chosen.js dropdown named "%s" not found',
- $field
- ));
+ 'Chosen.js dropdown named "%s" not found',
+ $field
+ ));
$containers = array();
foreach($formFields as $formField) {
@@ -357,11 +357,11 @@ public function theIFillInTheDropdownWith($field, $value)
&& preg_match('/field/', $containerCandidate->getAttribute('class'))
) {
$containers[] = $containerCandidate;
- }
}
-
- assertGreaterThan(0, count($containers), 'Chosen.js field container not found');
+ }
+ assertGreaterThan(0, count($containers), 'Chosen.js field container not found');
+
// Default to first visible container
$container = $containers[0];
@@ -373,9 +373,9 @@ public function theIFillInTheDropdownWith($field, $value)
$listEl = $container->find('xpath', sprintf('.//li[contains(normalize-space(string(.)), \'%s\')]', $value));
assertNotNull($listEl, sprintf(
- 'Chosen.js list element with title "%s" not found',
- $value
- ));
+ 'Chosen.js list element with title "%s" not found',
+ $value
+ ));
// Dropdown flyout might be animated
// $this->getSession()->wait(1000, 'jQuery(":animated").length == 0');
View
92 tests/injector/InjectorTest.php
@@ -442,7 +442,7 @@ public function testStaticInjections() {
public function testCustomObjectCreator() {
$injector = new Injector();
- $injector->setObjectCreator(new SSObjectCreator());
+ $injector->setObjectCreator(new SSObjectCreator($injector));
$config = array(
'OriginalRequirementsBackend',
'DummyRequirements' => array(
@@ -485,9 +485,65 @@ public function testSameNamedSingeltonPrototype() {
$again = $injector->get('NeedsBothCirculars');
$this->assertEquals($again->var, 'One');
}
+
+ public function testConvertServicePropertyOnCreate() {
+ // make sure convert service property is not called on direct calls to create, only on configured
+ // declarations to avoid un-needed function calls
+ $injector = new Injector();
+ $item = $injector->create('ConstructableObject', '%$TestObject');
+ $this->assertEquals('%$TestObject', $item->property);
+
+ // do it again but have test object configured as a constructor dependency
+ $injector = new Injector();
+ $config = array(
+ 'ConstructableObject' => array(
+ 'constructor' => array(
+ '%$TestObject'
+ )
+ )
+ );
+
+ $injector->load($config);
+ $item = $injector->get('ConstructableObject');
+ $this->assertTrue($item->property instanceof TestObject);
+
+ // and with a configured object defining TestObject to be something else!
+ $injector = new Injector(array('locator' => 'InjectorTestConfigLocator'));
+ $config = array(
+ 'ConstructableObject' => array(
+ 'constructor' => array(
+ '%$TestObject'
+ )
+ ),
+ );
+
+ $injector->load($config);
+ $item = $injector->get('ConstructableObject');
+ $this->assertTrue($item->property instanceof ConstructableObject);
+
+ $this->assertInstanceOf('OtherTestObject', $item->property->property);
+ }
+}
+
+class InjectorTestConfigLocator extends SilverStripeServiceConfigurationLocator implements TestOnly {
+ public function locateConfigFor($name) {
+ if ($name == 'TestObject') {
+ return array('class' => 'ConstructableObject', 'constructor' => array('%$OtherTestObject'));
+ }
+
+ return parent::locateConfigFor($name);
+ }
+}
+
+class ConstructableObject implements TestOnly {
+ public $property;
+
+ public function __construct($prop) {
+ $this->property = $prop;
+ }
}
-class TestObject {
+class TestObject implements TestOnly {
public $sampleService;
@@ -497,7 +553,7 @@ public function setSomething($v) {
}
-class OtherTestObject {
+class OtherTestObject implements TestOnly {
private $sampleService;
@@ -511,13 +567,13 @@ public function s() {
}
-class CircularOne {
+class CircularOne implements TestOnly {
public $circularTwo;
}
-class CircularTwo {
+class CircularTwo implements TestOnly {
public $circularOne;
@@ -528,23 +584,23 @@ public function __construct($value = null) {
}
}
-class NeedsBothCirculars {
+class NeedsBothCirculars implements TestOnly{
public $circularOne;
public $circularTwo;
public $var;
}
-class MyParentClass {
+class MyParentClass implements TestOnly {
public $one;
}
-class MyChildClass extends MyParentClass {
+class MyChildClass extends MyParentClass implements TestOnly {
}
-class DummyRequirements {
+class DummyRequirements implements TestOnly {
public $backend;
@@ -558,15 +614,15 @@ public function setBackend($backend) {
}
-class OriginalRequirementsBackend {
+class OriginalRequirementsBackend implements TestOnly {
}
-class NewRequirementsBackend {
+class NewRequirementsBackend implements TestOnly {
}
-class TestStaticInjections {
+class TestStaticInjections implements TestOnly {
public $backend;
static $dependencies = array(
@@ -582,13 +638,19 @@ class TestStaticInjections {
* @see https://github.com/silverstripe/sapphire
*/
class SSObjectCreator extends InjectionCreator {
+ private $injector;
+
+ public function __construct($injector) {
+ $this->injector = $injector;
+ }
- public function create(Injector $injector, $class, $params = array()) {
+ public function create($class, $params = array()) {
if (strpos($class, '(') === false) {
- return parent::create($injector, $class, $params);
+ return parent::create($class, $params);
} else {
list($class, $params) = self::parse_class_spec($class);
- return parent::create($injector, $class, $params);
+ $params = $this->injector->convertServiceProperty($params);
+ return parent::create($class, $params);
}
}

0 comments on commit f03ad7b

Please sign in to comment.
Something went wrong with that request. Please try again.