mirror of
https://github.com/kamilwylegala/cakephp2-php8.git
synced 2025-01-31 09:06:17 +00:00
Merge branch '2.1' of github.com:cakephp/cakephp into 2.1
This commit is contained in:
commit
7c0297a92c
40 changed files with 789 additions and 429 deletions
|
@ -268,7 +268,7 @@
|
||||||
* 'password' => 'password', //plaintext password (xcache.admin.pass)
|
* 'password' => 'password', //plaintext password (xcache.admin.pass)
|
||||||
* ));
|
* ));
|
||||||
*
|
*
|
||||||
* Memcache (http://www.danga.com/memcached/)
|
* Memcache (http://memcached.org/)
|
||||||
*
|
*
|
||||||
* Cache::config('default', array(
|
* Cache::config('default', array(
|
||||||
* 'engine' => 'Memcache', //[required]
|
* 'engine' => 'Memcache', //[required]
|
||||||
|
|
|
@ -24,7 +24,7 @@ App::uses('Debugger', 'Utility');
|
||||||
<p>For updates and important announcements, visit http://cakefest.org</p>
|
<p>For updates and important announcements, visit http://cakefest.org</p>
|
||||||
</iframe>
|
</iframe>
|
||||||
<h2><?php echo __d('cake_dev', 'Release Notes for CakePHP %s.', Configure::version()); ?></h2>
|
<h2><?php echo __d('cake_dev', 'Release Notes for CakePHP %s.', Configure::version()); ?></h2>
|
||||||
<a href="http://cakephp.org/changelogs/2.0.4"><?php __d('cake_dev', 'Read the changelog'); ?> </a>
|
<a href="http://cakephp.org/changelogs/2.0.5"><?php echo __d('cake_dev', 'Read the changelog'); ?> </a>
|
||||||
<?php
|
<?php
|
||||||
if (Configure::read('debug') > 0):
|
if (Configure::read('debug') > 0):
|
||||||
Debugger::checkSecurityKeys();
|
Debugger::checkSecurityKeys();
|
||||||
|
|
|
@ -17,4 +17,4 @@
|
||||||
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
|
||||||
*/
|
*/
|
||||||
$versionFile = file(CAKE . 'VERSION.txt');
|
$versionFile = file(CAKE . 'VERSION.txt');
|
||||||
return $config['Cake.version'] = array_pop($versionFile);
|
return $config['Cake.version'] = trim(array_pop($versionFile));
|
||||||
|
|
|
@ -545,6 +545,18 @@ class Controller extends Object implements CakeEventListener {
|
||||||
$pluginDot = $this->plugin . '.';
|
$pluginDot = $this->plugin . '.';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($pluginController && $this->plugin != null) {
|
||||||
|
$merge = array('components', 'helpers');
|
||||||
|
$appVars = get_class_vars($pluginController);
|
||||||
|
if (
|
||||||
|
($this->uses !== null || $this->uses !== false) &&
|
||||||
|
is_array($this->uses) && !empty($appVars['uses'])
|
||||||
|
) {
|
||||||
|
$this->uses = array_merge($this->uses, array_diff($appVars['uses'], $this->uses));
|
||||||
|
}
|
||||||
|
$this->_mergeVars($merge, $pluginController);
|
||||||
|
}
|
||||||
|
|
||||||
if (is_subclass_of($this, $this->_mergeParent) || !empty($pluginController)) {
|
if (is_subclass_of($this, $this->_mergeParent) || !empty($pluginController)) {
|
||||||
$appVars = get_class_vars($this->_mergeParent);
|
$appVars = get_class_vars($this->_mergeParent);
|
||||||
$uses = $appVars['uses'];
|
$uses = $appVars['uses'];
|
||||||
|
@ -567,18 +579,6 @@ class Controller extends Object implements CakeEventListener {
|
||||||
}
|
}
|
||||||
$this->_mergeVars($merge, $this->_mergeParent, true);
|
$this->_mergeVars($merge, $this->_mergeParent, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($pluginController && $this->plugin != null) {
|
|
||||||
$merge = array('components', 'helpers');
|
|
||||||
$appVars = get_class_vars($pluginController);
|
|
||||||
if (
|
|
||||||
($this->uses !== null || $this->uses !== false) &&
|
|
||||||
is_array($this->uses) && !empty($appVars['uses'])
|
|
||||||
) {
|
|
||||||
$this->uses = array_merge($this->uses, array_diff($appVars['uses'], $this->uses));
|
|
||||||
}
|
|
||||||
$this->_mergeVars($merge, $pluginController);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -212,7 +212,7 @@ class App {
|
||||||
*
|
*
|
||||||
* @param string $type type of path
|
* @param string $type type of path
|
||||||
* @param string $plugin name of plugin
|
* @param string $plugin name of plugin
|
||||||
* @return string array
|
* @return array
|
||||||
* @link http://book.cakephp.org/2.0/en/core-utility-libraries/app.html#App::path
|
* @link http://book.cakephp.org/2.0/en/core-utility-libraries/app.html#App::path
|
||||||
*/
|
*/
|
||||||
public static function path($type, $plugin = null) {
|
public static function path($type, $plugin = null) {
|
||||||
|
@ -387,7 +387,7 @@ class App {
|
||||||
* `App::core('Cache/Engine'); will return the full path to the cache engines package`
|
* `App::core('Cache/Engine'); will return the full path to the cache engines package`
|
||||||
*
|
*
|
||||||
* @param string $type
|
* @param string $type
|
||||||
* @return string full path to package
|
* @return array full path to package
|
||||||
* @link http://book.cakephp.org/2.0/en/core-utility-libraries/app.html#App::core
|
* @link http://book.cakephp.org/2.0/en/core-utility-libraries/app.html#App::core
|
||||||
*/
|
*/
|
||||||
public static function core($type) {
|
public static function core($type) {
|
||||||
|
@ -580,7 +580,7 @@ class App {
|
||||||
* based on Inflector::underscore($name) . ".$ext";
|
* based on Inflector::underscore($name) . ".$ext";
|
||||||
* @param array $search paths to search for files, array('path 1', 'path 2', 'path 3');
|
* @param array $search paths to search for files, array('path 1', 'path 2', 'path 3');
|
||||||
* @param string $file full name of the file to search for including extension
|
* @param string $file full name of the file to search for including extension
|
||||||
* @param boolean $return, return the loaded file, the file must have a return
|
* @param boolean $return Return the loaded file, the file must have a return
|
||||||
* statement in it to work: return $variable;
|
* statement in it to work: return $variable;
|
||||||
* @return boolean true if Class is already in memory or if file is found and loaded, false if not
|
* @return boolean true if Class is already in memory or if file is found and loaded, false if not
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -224,7 +224,7 @@ class CakeEventManager {
|
||||||
*/
|
*/
|
||||||
public function dispatch($event) {
|
public function dispatch($event) {
|
||||||
if (is_string($event)) {
|
if (is_string($event)) {
|
||||||
$Event = new CakeEvent($event);
|
$event = new CakeEvent($event);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$this->_isGlobal) {
|
if (!$this->_isGlobal) {
|
||||||
|
|
|
@ -185,6 +185,18 @@ class I18n {
|
||||||
if (is_array($trans)) {
|
if (is_array($trans)) {
|
||||||
if (isset($trans[$plurals])) {
|
if (isset($trans[$plurals])) {
|
||||||
$trans = $trans[$plurals];
|
$trans = $trans[$plurals];
|
||||||
|
} else {
|
||||||
|
trigger_error(
|
||||||
|
__d('cake_dev',
|
||||||
|
'Missing plural form translation for "%s" in "%s" domain, "%s" locale. ' .
|
||||||
|
' Check your po file for correct plurals and valid Plural-Forms header.',
|
||||||
|
$singular,
|
||||||
|
$domain,
|
||||||
|
$_this->_lang
|
||||||
|
),
|
||||||
|
E_USER_WARNING
|
||||||
|
);
|
||||||
|
$trans = $trans[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (strlen($trans)) {
|
if (strlen($trans)) {
|
||||||
|
|
|
@ -982,7 +982,7 @@ class Multibyte {
|
||||||
$parts = array();
|
$parts = array();
|
||||||
$maxchars = floor(($length * 3) / 4);
|
$maxchars = floor(($length * 3) / 4);
|
||||||
while (strlen($string) > $maxchars) {
|
while (strlen($string) > $maxchars) {
|
||||||
$i = $maxchars;
|
$i = (int)$maxchars;
|
||||||
$test = ord($string[$i]);
|
$test = ord($string[$i]);
|
||||||
while ($test >= 128 && $test <= 191) {
|
while ($test >= 128 && $test <= 191) {
|
||||||
$i--;
|
$i--;
|
||||||
|
|
|
@ -369,7 +369,10 @@ class TranslateBehavior extends ModelBehavior {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bind translation for fields, optionally with hasMany association for
|
* Bind translation for fields, optionally with hasMany association for
|
||||||
* fake field
|
* fake field.
|
||||||
|
*
|
||||||
|
* *Note* You should avoid binding translations that overlap existing model properties.
|
||||||
|
* This can cause un-expected and un-desirable behavior.
|
||||||
*
|
*
|
||||||
* @param Model $model instance of model
|
* @param Model $model instance of model
|
||||||
* @param string|array $fields string with field or array(field1, field2=>AssocName, field3)
|
* @param string|array $fields string with field or array(field1, field2=>AssocName, field3)
|
||||||
|
@ -392,6 +395,11 @@ class TranslateBehavior extends ModelBehavior {
|
||||||
$field = $key;
|
$field = $key;
|
||||||
$association = $value;
|
$association = $value;
|
||||||
}
|
}
|
||||||
|
if ($association === 'name') {
|
||||||
|
throw new CakeException(
|
||||||
|
__d('cake_dev', 'You cannot bind a translation named "name".')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (array_key_exists($field, $this->settings[$model->alias])) {
|
if (array_key_exists($field, $this->settings[$model->alias])) {
|
||||||
unset($this->settings[$model->alias][$field]);
|
unset($this->settings[$model->alias][$field]);
|
||||||
|
|
|
@ -70,13 +70,6 @@ class CakeSession {
|
||||||
*/
|
*/
|
||||||
public static $lastError = null;
|
public static $lastError = null;
|
||||||
|
|
||||||
/**
|
|
||||||
* 'Security.level' setting, "high", "medium", or "low".
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
public static $security = null;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start time for this session.
|
* Start time for this session.
|
||||||
*
|
*
|
||||||
|
@ -121,7 +114,7 @@ class CakeSession {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Number of requests that can occur during a session time without the session being renewed.
|
* Number of requests that can occur during a session time without the session being renewed.
|
||||||
* This feature is only used when `Session.harden` is set to true.
|
* This feature is only used when `Session.autoRegenerate` is set to true.
|
||||||
*
|
*
|
||||||
* @var integer
|
* @var integer
|
||||||
* @see CakeSession::_checkValid()
|
* @see CakeSession::_checkValid()
|
||||||
|
|
|
@ -413,7 +413,7 @@ class DataSource extends Object {
|
||||||
* @access public
|
* @access public
|
||||||
*/
|
*/
|
||||||
public function getSchemaName() {
|
public function getSchemaName() {
|
||||||
return false;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -723,7 +723,7 @@ class Postgres extends DboSource {
|
||||||
break;
|
break;
|
||||||
case 'binary':
|
case 'binary':
|
||||||
case 'bytea':
|
case 'bytea':
|
||||||
$resultRow[$table][$column] = stream_get_contents($row[$index]);
|
$resultRow[$table][$column] = is_null($row[$index]) ? null : stream_get_contents($row[$index]);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
$resultRow[$table][$column] = $row[$index];
|
$resultRow[$table][$column] = $row[$index];
|
||||||
|
|
|
@ -484,7 +484,7 @@ class DboSource extends DataSource {
|
||||||
if ($this->hasResult()) {
|
if ($this->hasResult()) {
|
||||||
return $this->_result->rowCount();
|
return $this->_result->rowCount();
|
||||||
}
|
}
|
||||||
return null;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -930,14 +930,14 @@ class DboSource extends DataSource {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($quote) {
|
if ($quote) {
|
||||||
if ($schema && isset($schemaName)) {
|
if ($schema && !empty($schemaName)) {
|
||||||
if (false == strstr($table, '.')) {
|
if (false == strstr($table, '.')) {
|
||||||
return $this->name($schemaName) . '.' . $this->name($table);
|
return $this->name($schemaName) . '.' . $this->name($table);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $this->name($table);
|
return $this->name($table);
|
||||||
}
|
}
|
||||||
if ($schema && isset($schemaName)) {
|
if ($schema && !empty($schemaName)) {
|
||||||
if (false == strstr($table, '.')) {
|
if (false == strstr($table, '.')) {
|
||||||
return $schemaName . '.' . $table;
|
return $schemaName . '.' . $table;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1203,7 +1203,17 @@ class Model extends Object implements CakeEventListener {
|
||||||
$timeFields = array('H' => 'hour', 'i' => 'min', 's' => 'sec');
|
$timeFields = array('H' => 'hour', 'i' => 'min', 's' => 'sec');
|
||||||
$date = array();
|
$date = array();
|
||||||
|
|
||||||
if (isset($data['hour']) && isset($data['meridian']) && $data['hour'] != 12 && 'pm' == $data['meridian']) {
|
if (isset($data['meridian']) && empty($data['meridian'])) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
isset($data['hour']) &&
|
||||||
|
isset($data['meridian']) &&
|
||||||
|
!empty($data['hour']) &&
|
||||||
|
$data['hour'] != 12 &&
|
||||||
|
'pm' == $data['meridian']
|
||||||
|
) {
|
||||||
$data['hour'] = $data['hour'] + 12;
|
$data['hour'] = $data['hour'] + 12;
|
||||||
}
|
}
|
||||||
if (isset($data['hour']) && isset($data['meridian']) && $data['hour'] == 12 && 'am' == $data['meridian']) {
|
if (isset($data['hour']) && isset($data['meridian']) && $data['hour'] == 12 && 'am' == $data['meridian']) {
|
||||||
|
@ -1213,9 +1223,7 @@ class Model extends Object implements CakeEventListener {
|
||||||
foreach ($timeFields as $key => $val) {
|
foreach ($timeFields as $key => $val) {
|
||||||
if (!isset($data[$val]) || $data[$val] === '0' || $data[$val] === '00') {
|
if (!isset($data[$val]) || $data[$val] === '0' || $data[$val] === '00') {
|
||||||
$data[$val] = '00';
|
$data[$val] = '00';
|
||||||
} elseif ($data[$val] === '') {
|
} elseif ($data[$val] !== '') {
|
||||||
$data[$val] = '';
|
|
||||||
} else {
|
|
||||||
$data[$val] = sprintf('%02d', $data[$val]);
|
$data[$val] = sprintf('%02d', $data[$val]);
|
||||||
}
|
}
|
||||||
if (!empty($data[$val])) {
|
if (!empty($data[$val])) {
|
||||||
|
@ -2810,6 +2818,13 @@ class Model extends Object implements CakeEventListener {
|
||||||
foreach ($results as $result) {
|
foreach ($results as $result) {
|
||||||
$result['children'] = array();
|
$result['children'] = array();
|
||||||
$id = $result[$this->alias][$this->primaryKey];
|
$id = $result[$this->alias][$this->primaryKey];
|
||||||
|
if (!isset($result[$this->alias]['parent_id'])) {
|
||||||
|
trigger_error(
|
||||||
|
__d('cake_dev', 'You cannot use find("threaded") on models without a "parent_id" field.'),
|
||||||
|
E_USER_WARNING
|
||||||
|
);
|
||||||
|
return $return;
|
||||||
|
}
|
||||||
$parentId = $result[$this->alias]['parent_id'];
|
$parentId = $result[$this->alias]['parent_id'];
|
||||||
if (isset($idMap[$id]['children'])) {
|
if (isset($idMap[$id]['children'])) {
|
||||||
$idMap[$id] = array_merge($result, (array)$idMap[$id]);
|
$idMap[$id] = array_merge($result, (array)$idMap[$id]);
|
||||||
|
|
|
@ -107,7 +107,7 @@ class CakeRequest implements ArrayAccess {
|
||||||
'Android', 'AvantGo', 'BlackBerry', 'DoCoMo', 'Fennec', 'iPod', 'iPhone',
|
'Android', 'AvantGo', 'BlackBerry', 'DoCoMo', 'Fennec', 'iPod', 'iPhone',
|
||||||
'J2ME', 'MIDP', 'NetFront', 'Nokia', 'Opera Mini', 'Opera Mobi', 'PalmOS', 'PalmSource',
|
'J2ME', 'MIDP', 'NetFront', 'Nokia', 'Opera Mini', 'Opera Mobi', 'PalmOS', 'PalmSource',
|
||||||
'portalmmm', 'Plucker', 'ReqwirelessWeb', 'SonyEricsson', 'Symbian', 'UP\\.Browser',
|
'portalmmm', 'Plucker', 'ReqwirelessWeb', 'SonyEricsson', 'Symbian', 'UP\\.Browser',
|
||||||
'webOS', 'Windows CE', 'Xiino'
|
'webOS', 'Windows CE', 'Windows Phone OS', 'Xiino'
|
||||||
)),
|
)),
|
||||||
'requested' => array('param' => 'requested', 'value' => 1)
|
'requested' => array('param' => 'requested', 'value' => 1)
|
||||||
);
|
);
|
||||||
|
|
|
@ -662,14 +662,12 @@ class CakeEmail {
|
||||||
}
|
}
|
||||||
|
|
||||||
$headers['MIME-Version'] = '1.0';
|
$headers['MIME-Version'] = '1.0';
|
||||||
if (!empty($this->_attachments)) {
|
if (!empty($this->_attachments) || $this->_emailFormat === 'both') {
|
||||||
$headers['Content-Type'] = 'multipart/mixed; boundary="' . $this->_boundary . '"';
|
$headers['Content-Type'] = 'multipart/mixed; boundary="' . $this->_boundary . '"';
|
||||||
} elseif ($this->_emailFormat === 'text') {
|
} elseif ($this->_emailFormat === 'text') {
|
||||||
$headers['Content-Type'] = 'text/plain; charset=' . $this->charset;
|
$headers['Content-Type'] = 'text/plain; charset=' . $this->charset;
|
||||||
} elseif ($this->_emailFormat === 'html') {
|
} elseif ($this->_emailFormat === 'html') {
|
||||||
$headers['Content-Type'] = 'text/html; charset=' . $this->charset;
|
$headers['Content-Type'] = 'text/html; charset=' . $this->charset;
|
||||||
} elseif ($this->_emailFormat === 'both') {
|
|
||||||
$headers['Content-Type'] = 'multipart/alternative; boundary="alt-' . $this->_boundary . '"';
|
|
||||||
}
|
}
|
||||||
$headers['Content-Transfer-Encoding'] = $this->_getContentTransferEncoding();
|
$headers['Content-Transfer-Encoding'] = $this->_getContentTransferEncoding();
|
||||||
|
|
||||||
|
@ -835,10 +833,37 @@ class CakeEmail {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attachments
|
* Add attachments to the email message
|
||||||
|
*
|
||||||
|
* Attachments can be defined in a few forms depending on how much control you need:
|
||||||
|
*
|
||||||
|
* Attach a single file:
|
||||||
|
*
|
||||||
|
* {{{
|
||||||
|
* $email->attachments('path/to/file');
|
||||||
|
* }}}
|
||||||
|
*
|
||||||
|
* Attach a file with a different filename:
|
||||||
|
*
|
||||||
|
* {{{
|
||||||
|
* $email->attachments(array('custom_name.txt' => 'path/to/file.txt'));
|
||||||
|
* }}}
|
||||||
|
*
|
||||||
|
* Attach a file and specify additional properties:
|
||||||
|
*
|
||||||
|
* {{{
|
||||||
|
* $email->attachments(array('custom_name.png' => array(
|
||||||
|
* 'file' => 'path/to/file',
|
||||||
|
* 'mimetype' => 'image/png',
|
||||||
|
* 'contentId' => 'abc123'
|
||||||
|
* ));
|
||||||
|
* }}}
|
||||||
|
*
|
||||||
|
* The `contentId` key allows you to specify an inline attachment. In your email text, you
|
||||||
|
* can use `<img src="cid:abc123" />` to display the image inline.
|
||||||
*
|
*
|
||||||
* @param mixed $attachments String with the filename or array with filenames
|
* @param mixed $attachments String with the filename or array with filenames
|
||||||
* @return mixed
|
* @return mixed Either the array of attachments when getting or $this when setting.
|
||||||
* @throws SocketException
|
* @throws SocketException
|
||||||
*/
|
*/
|
||||||
public function attachments($attachments = null) {
|
public function attachments($attachments = null) {
|
||||||
|
@ -936,34 +961,9 @@ class CakeEmail {
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->_textMessage = $this->_htmlMessage = '';
|
$this->_textMessage = $this->_htmlMessage = '';
|
||||||
if ($content !== null) {
|
|
||||||
if ($this->_emailFormat === 'text') {
|
|
||||||
$this->_textMessage = $content;
|
|
||||||
} elseif ($this->_emailFormat === 'html') {
|
|
||||||
$this->_htmlMessage = $content;
|
|
||||||
} elseif ($this->_emailFormat === 'both') {
|
|
||||||
$this->_textMessage = $this->_htmlMessage = $content;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->_createBoundary();
|
$this->_createBoundary();
|
||||||
|
$this->_message = $this->_render($this->_wrap($content));
|
||||||
|
|
||||||
$message = $this->_wrap($content);
|
|
||||||
if (empty($this->_template)) {
|
|
||||||
$message = $this->_formatMessage($message);
|
|
||||||
} else {
|
|
||||||
$message = $this->_render($message);
|
|
||||||
}
|
|
||||||
$message[] = '';
|
|
||||||
$this->_message = $message;
|
|
||||||
|
|
||||||
if (!empty($this->_attachments)) {
|
|
||||||
$this->_attachFiles();
|
|
||||||
|
|
||||||
$this->_message[] = '';
|
|
||||||
$this->_message[] = '--' . $this->_boundary . '--';
|
|
||||||
$this->_message[] = '';
|
|
||||||
}
|
|
||||||
$contents = $this->transportClass()->send($this);
|
$contents = $this->transportClass()->send($this);
|
||||||
if (!empty($this->_config['log'])) {
|
if (!empty($this->_config['log'])) {
|
||||||
$level = LOG_DEBUG;
|
$level = LOG_DEBUG;
|
||||||
|
@ -1213,6 +1213,7 @@ class CakeEmail {
|
||||||
}
|
}
|
||||||
$formatted[] = trim(substr($tmpLine, 0, $lastSpace));
|
$formatted[] = trim(substr($tmpLine, 0, $lastSpace));
|
||||||
$tmpLine = substr($tmpLine, $lastSpace + 1);
|
$tmpLine = substr($tmpLine, $lastSpace + 1);
|
||||||
|
|
||||||
$tmpLineLength = strlen($tmpLine);
|
$tmpLineLength = strlen($tmpLine);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1237,71 +1238,183 @@ class CakeEmail {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attach files by adding file contents inside boundaries.
|
* Attach non-embedded files by adding file contents inside boundaries.
|
||||||
*
|
*
|
||||||
* @return void
|
* @return array An array of lines to add to the message
|
||||||
*/
|
*/
|
||||||
protected function _attachFiles() {
|
protected function _attachFiles() {
|
||||||
|
$msg = array();
|
||||||
foreach ($this->_attachments as $filename => $fileInfo) {
|
foreach ($this->_attachments as $filename => $fileInfo) {
|
||||||
$handle = fopen($fileInfo['file'], 'rb');
|
if (!empty($fileInfo['contentId'])) {
|
||||||
$data = fread($handle, filesize($fileInfo['file']));
|
continue;
|
||||||
$data = chunk_split(base64_encode($data)) ;
|
|
||||||
fclose($handle);
|
|
||||||
|
|
||||||
$this->_message[] = '--' . $this->_boundary;
|
|
||||||
$this->_message[] = 'Content-Type: ' . $fileInfo['mimetype'];
|
|
||||||
$this->_message[] = 'Content-Transfer-Encoding: base64';
|
|
||||||
if (empty($fileInfo['contentId'])) {
|
|
||||||
$this->_message[] = 'Content-Disposition: attachment; filename="' . $filename . '"';
|
|
||||||
} else {
|
|
||||||
$this->_message[] = 'Content-ID: <' . $fileInfo['contentId'] . '>';
|
|
||||||
$this->_message[] = 'Content-Disposition: inline; filename="' . $filename . '"';
|
|
||||||
}
|
}
|
||||||
$this->_message[] = '';
|
$data = $this->_readFile($fileInfo['file']);
|
||||||
$this->_message[] = $data;
|
|
||||||
$this->_message[] = '';
|
$msg[] = '--' . $this->_boundary;
|
||||||
|
$msg[] = 'Content-Type: ' . $fileInfo['mimetype'];
|
||||||
|
$msg[] = 'Content-Transfer-Encoding: base64';
|
||||||
|
$msg[] = 'Content-Disposition: attachment; filename="' . $filename . '"';
|
||||||
|
$msg[] = '';
|
||||||
|
$msg[] = $data;
|
||||||
|
$msg[] = '';
|
||||||
}
|
}
|
||||||
|
return $msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Format the message by seeing if it has attachments.
|
* Read the file contents and return a base64 version of the file contents.
|
||||||
*
|
*
|
||||||
* @param array $message Message to format
|
* @param string $file The file to read.
|
||||||
* @return array
|
* @return string File contents in base64 encoding
|
||||||
*/
|
*/
|
||||||
protected function _formatMessage($message) {
|
protected function _readFile($file) {
|
||||||
if (!empty($this->_attachments)) {
|
$handle = fopen($file, 'rb');
|
||||||
$prefix = array('--' . $this->_boundary);
|
$data = fread($handle, filesize($file));
|
||||||
if ($this->_emailFormat === 'text') {
|
$data = chunk_split(base64_encode($data)) ;
|
||||||
$prefix[] = 'Content-Type: text/plain; charset=' . $this->charset;
|
fclose($handle);
|
||||||
} elseif ($this->_emailFormat === 'html') {
|
return $data;
|
||||||
$prefix[] = 'Content-Type: text/html; charset=' . $this->charset;
|
|
||||||
} elseif ($this->_emailFormat === 'both') {
|
|
||||||
$prefix[] = 'Content-Type: multipart/alternative; boundary="alt-' . $this->_boundary . '"';
|
|
||||||
}
|
|
||||||
$prefix[] = 'Content-Transfer-Encoding: ' . $this->_getContentTransferEncoding();
|
|
||||||
$prefix[] = '';
|
|
||||||
$message = array_merge($prefix, $message);
|
|
||||||
}
|
|
||||||
|
|
||||||
$tmp = array();
|
|
||||||
foreach ($message as $msg) {
|
|
||||||
$tmp[] = $this->_encodeString($msg, $this->charset);
|
|
||||||
}
|
|
||||||
$message = $tmp;
|
|
||||||
|
|
||||||
return $message;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render the contents using the current layout and template.
|
* Attach inline/embedded files to the message.
|
||||||
|
*
|
||||||
|
* @return array An array of lines to add to the message
|
||||||
|
*/
|
||||||
|
protected function _attachInlineFiles() {
|
||||||
|
$msg = array();
|
||||||
|
foreach ($this->_attachments as $filename => $fileInfo) {
|
||||||
|
if (empty($fileInfo['contentId'])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$data = $this->_readFile($fileInfo['file']);
|
||||||
|
|
||||||
|
$msg[] = '--' . $this->_boundary;
|
||||||
|
$msg[] = 'Content-Type: ' . $fileInfo['mimetype'];
|
||||||
|
$msg[] = 'Content-Transfer-Encoding: base64';
|
||||||
|
$msg[] = 'Content-ID: <' . $fileInfo['contentId'] . '>';
|
||||||
|
$msg[] = 'Content-Disposition: inline; filename="' . $filename . '"';
|
||||||
|
$msg[] = '';
|
||||||
|
$msg[] = $data;
|
||||||
|
$msg[] = '';
|
||||||
|
}
|
||||||
|
return $msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render the body of the email.
|
||||||
*
|
*
|
||||||
* @param string $content Content to render
|
* @param string $content Content to render
|
||||||
* @return array Email ready to be sent
|
* @return array Email body ready to be sent
|
||||||
*/
|
*/
|
||||||
protected function _render($content) {
|
protected function _render($content) {
|
||||||
$viewClass = $this->_viewRender;
|
$content = implode("\n", $content);
|
||||||
|
$rendered = $this->_renderTemplates($content);
|
||||||
|
|
||||||
|
$msg = array();
|
||||||
|
|
||||||
|
$contentIds = array_filter((array)Set::classicExtract($this->_attachments, '{s}.contentId'));
|
||||||
|
$hasInlineAttachments = count($contentIds) > 0;
|
||||||
|
$hasAttachments = !empty($this->_attachments);
|
||||||
|
$hasMultipleTypes = count($rendered) > 1;
|
||||||
|
|
||||||
|
$boundary = $relBoundary = $textBoundary = $this->_boundary;
|
||||||
|
|
||||||
|
if ($hasInlineAttachments) {
|
||||||
|
$msg[] = '--' . $boundary;
|
||||||
|
$msg[] = 'Content-Type: multipart/related; boundary="rel-' . $boundary . '"';
|
||||||
|
$msg[] = '';
|
||||||
|
$relBoundary = 'rel-' . $boundary;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($hasMultipleTypes) {
|
||||||
|
$msg[] = '--' . $relBoundary;
|
||||||
|
$msg[] = 'Content-Type: multipart/alternative; boundary="alt-' . $boundary . '"';
|
||||||
|
$msg[] = '';
|
||||||
|
$textBoundary = 'alt-' . $boundary;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($rendered['text'])) {
|
||||||
|
if ($textBoundary !== $boundary || $hasAttachments) {
|
||||||
|
$msg[] = '--' . $textBoundary;
|
||||||
|
$msg[] = 'Content-Type: text/plain; charset=' . $this->charset;
|
||||||
|
$msg[] = 'Content-Transfer-Encoding: ' . $this->_getContentTransferEncoding();
|
||||||
|
$msg[] = '';
|
||||||
|
}
|
||||||
|
$this->_textMessage = $rendered['text'];
|
||||||
|
$content = explode("\n", $this->_textMessage);
|
||||||
|
$msg = array_merge($msg, $content);
|
||||||
|
$msg[] = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($rendered['html'])) {
|
||||||
|
if ($textBoundary !== $boundary || $hasAttachments) {
|
||||||
|
$msg[] = '--' . $textBoundary;
|
||||||
|
$msg[] = 'Content-Type: text/html; charset=' . $this->charset;
|
||||||
|
$msg[] = 'Content-Transfer-Encoding: ' . $this->_getContentTransferEncoding();
|
||||||
|
$msg[] = '';
|
||||||
|
}
|
||||||
|
$this->_htmlMessage = $rendered['html'];
|
||||||
|
$content = explode("\n", $this->_htmlMessage);
|
||||||
|
$msg = array_merge($msg, $content);
|
||||||
|
$msg[] = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($hasMultipleTypes) {
|
||||||
|
$msg[] = '--' . $textBoundary . '--';
|
||||||
|
$msg[] = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($hasInlineAttachments) {
|
||||||
|
$attachments = $this->_attachInlineFiles();
|
||||||
|
$msg = array_merge($msg, $attachments);
|
||||||
|
$msg[] = '';
|
||||||
|
$msg[] = '--' . $relBoundary . '--';
|
||||||
|
$msg[] = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($hasAttachments) {
|
||||||
|
$attachments = $this->_attachFiles();
|
||||||
|
$msg = array_merge($msg, $attachments);
|
||||||
|
}
|
||||||
|
if ($hasAttachments || $hasMultipleTypes) {
|
||||||
|
$msg[] = '';
|
||||||
|
$msg[] = '--' . $boundary . '--';
|
||||||
|
$msg[] = '';
|
||||||
|
}
|
||||||
|
return $msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the text body types that are in this email message
|
||||||
|
*
|
||||||
|
* @return array Array of types. Valid types are 'text' and 'html'
|
||||||
|
*/
|
||||||
|
protected function _getTypes() {
|
||||||
|
$types = array($this->_emailFormat);
|
||||||
|
if ($this->_emailFormat == 'both') {
|
||||||
|
$types = array('html', 'text');
|
||||||
|
}
|
||||||
|
return $types;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build and set all the view properties needed to render the templated emails.
|
||||||
|
* If there is no template set, the $content will be returned in a hash
|
||||||
|
* of the text content types for the email.
|
||||||
|
*
|
||||||
|
* @param string $content The content passed in from send() in most cases.
|
||||||
|
* @return array The rendered content with html and text keys.
|
||||||
|
*/
|
||||||
|
protected function _renderTemplates($content) {
|
||||||
|
$types = $this->_getTypes();
|
||||||
|
$rendered = array();
|
||||||
|
if (empty($this->_template)) {
|
||||||
|
foreach ($types as $type) {
|
||||||
|
$rendered[$type] = $this->_encodeString($content, $this->charset);
|
||||||
|
}
|
||||||
|
return $rendered;
|
||||||
|
}
|
||||||
|
$viewClass = $this->_viewRender;
|
||||||
if ($viewClass !== 'View') {
|
if ($viewClass !== 'View') {
|
||||||
list($plugin, $viewClass) = pluginSplit($viewClass, true);
|
list($plugin, $viewClass) = pluginSplit($viewClass, true);
|
||||||
$viewClass .= 'View';
|
$viewClass .= 'View';
|
||||||
|
@ -1311,7 +1424,6 @@ class CakeEmail {
|
||||||
$View = new $viewClass(null);
|
$View = new $viewClass(null);
|
||||||
$View->viewVars = $this->_viewVars;
|
$View->viewVars = $this->_viewVars;
|
||||||
$View->helpers = $this->_helpers;
|
$View->helpers = $this->_helpers;
|
||||||
$msg = array();
|
|
||||||
|
|
||||||
list($templatePlugin, $template) = pluginSplit($this->_template);
|
list($templatePlugin, $template) = pluginSplit($this->_template);
|
||||||
list($layoutPlugin, $layout) = pluginSplit($this->_layout);
|
list($layoutPlugin, $layout) = pluginSplit($this->_layout);
|
||||||
|
@ -1321,73 +1433,16 @@ class CakeEmail {
|
||||||
$View->plugin = $layoutPlugin;
|
$View->plugin = $layoutPlugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
$content = implode("\n", $content);
|
foreach ($types as $type) {
|
||||||
|
$View->set('content', $content);
|
||||||
if ($this->_emailFormat === 'both') {
|
|
||||||
$originalContent = $content;
|
|
||||||
if (!empty($this->_attachments)) {
|
|
||||||
$msg[] = '--' . $this->_boundary;
|
|
||||||
$msg[] = 'Content-Type: multipart/alternative; boundary="alt-' . $this->_boundary . '"';
|
|
||||||
$msg[] = '';
|
|
||||||
}
|
|
||||||
$msg[] = '--alt-' . $this->_boundary;
|
|
||||||
$msg[] = 'Content-Type: text/plain; charset=' . $this->charset;
|
|
||||||
$msg[] = 'Content-Transfer-Encoding: ' . $this->_getContentTransferEncoding();
|
|
||||||
$msg[] = '';
|
|
||||||
|
|
||||||
$View->viewPath = $View->layoutPath = 'Emails' . DS . 'text';
|
|
||||||
$View->viewVars['content'] = $originalContent;
|
|
||||||
$this->_textMessage = str_replace(array("\r\n", "\r"), "\n", $View->render($template, $layout));
|
|
||||||
$content = explode("\n", $this->_textMessage);
|
|
||||||
$msg = array_merge($msg, $content);
|
|
||||||
|
|
||||||
$msg[] = '';
|
|
||||||
$msg[] = '--alt-' . $this->_boundary;
|
|
||||||
$msg[] = 'Content-Type: text/html; charset=' . $this->charset;
|
|
||||||
$msg[] = 'Content-Transfer-Encoding: ' . $this->_getContentTransferEncoding();
|
|
||||||
$msg[] = '';
|
|
||||||
|
|
||||||
$View->viewPath = $View->layoutPath = 'Emails' . DS . 'html';
|
|
||||||
$View->viewVars['content'] = $originalContent;
|
|
||||||
$View->hasRendered = false;
|
$View->hasRendered = false;
|
||||||
$this->_htmlMessage = str_replace(array("\r\n", "\r"), "\n", $View->render($template, $layout));
|
$View->viewPath = $View->layoutPath = 'Emails' . DS . $type;
|
||||||
$content = explode("\n", $this->_htmlMessage);
|
|
||||||
$msg = array_merge($msg, $content);
|
$render = $View->render($template, $layout);
|
||||||
|
$render = str_replace(array("\r\n", "\r"), "\n", $render);
|
||||||
$msg[] = '';
|
$rendered[$type] = $this->_encodeString($render, $this->charset);
|
||||||
$msg[] = '--alt-' . $this->_boundary . '--';
|
|
||||||
$msg[] = '';
|
|
||||||
|
|
||||||
return $msg;
|
|
||||||
}
|
}
|
||||||
|
return $rendered;
|
||||||
if (!empty($this->_attachments)) {
|
|
||||||
if ($this->_emailFormat === 'html') {
|
|
||||||
$msg[] = '';
|
|
||||||
$msg[] = '--' . $this->_boundary;
|
|
||||||
$msg[] = 'Content-Type: text/html; charset=' . $this->charset;
|
|
||||||
$msg[] = 'Content-Transfer-Encoding: ' . $this->_getContentTransferEncoding();
|
|
||||||
$msg[] = '';
|
|
||||||
} else {
|
|
||||||
$msg[] = '--' . $this->_boundary;
|
|
||||||
$msg[] = 'Content-Type: text/plain; charset=' . $this->charset;
|
|
||||||
$msg[] = 'Content-Transfer-Encoding: ' . $this->_getContentTransferEncoding();
|
|
||||||
$msg[] = '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$View->viewPath = $View->layoutPath = 'Emails' . DS . $this->_emailFormat;
|
|
||||||
$View->viewVars['content'] = $content;
|
|
||||||
$rendered = $this->_encodeString($View->render($template, $layout), $this->charset);
|
|
||||||
$content = explode("\n", $rendered);
|
|
||||||
|
|
||||||
if ($this->_emailFormat === 'html') {
|
|
||||||
$this->_htmlMessage = $rendered;
|
|
||||||
} else {
|
|
||||||
$this->_textMessage = $rendered;
|
|
||||||
}
|
|
||||||
|
|
||||||
return array_merge($msg, $content);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -174,6 +174,20 @@ class Router {
|
||||||
return self::$_namedExpressions;
|
return self::$_namedExpressions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resource map getter & setter.
|
||||||
|
*
|
||||||
|
* @param array $resourceMap Resource map
|
||||||
|
* @return mixed
|
||||||
|
* @see Router::$_resourceMap
|
||||||
|
*/
|
||||||
|
public static function resourceMap($resourceMap = null) {
|
||||||
|
if ($resourceMap === null) {
|
||||||
|
return self::$_resourceMap;
|
||||||
|
}
|
||||||
|
self::$_resourceMap = $resourceMap;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Connects a new Route in the router.
|
* Connects a new Route in the router.
|
||||||
*
|
*
|
||||||
|
|
|
@ -228,12 +228,6 @@ MSGBLOC;
|
||||||
$expect = str_replace('{CONTENTTYPE}', 'text/html; charset=UTF-8', $message);
|
$expect = str_replace('{CONTENTTYPE}', 'text/html; charset=UTF-8', $message);
|
||||||
$this->assertTrue($this->Controller->EmailTest->send('This is the body of the message'));
|
$this->assertTrue($this->Controller->EmailTest->send('This is the body of the message'));
|
||||||
$this->assertEquals(DebugCompTransport::$lastEmail, $this->__osFix($expect));
|
$this->assertEquals(DebugCompTransport::$lastEmail, $this->__osFix($expect));
|
||||||
|
|
||||||
// TODO: better test for format of message sent?
|
|
||||||
$this->Controller->EmailTest->sendAs = 'both';
|
|
||||||
$expect = str_replace('{CONTENTTYPE}', 'multipart/alternative; boundary="alt-"', $message);
|
|
||||||
$this->assertTrue($this->Controller->EmailTest->send('This is the body of the message'));
|
|
||||||
$this->assertEquals(preg_replace('/alt-[a-z0-9]{32}/i', 'alt-', DebugCompTransport::$lastEmail), $this->__osFix($expect));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -307,13 +301,29 @@ HTMLBLOC;
|
||||||
$this->assertEquals(DebugCompTransport::$lastEmail, $this->__osFix($expect));
|
$this->assertEquals(DebugCompTransport::$lastEmail, $this->__osFix($expect));
|
||||||
|
|
||||||
$this->Controller->EmailTest->sendAs = 'both';
|
$this->Controller->EmailTest->sendAs = 'both';
|
||||||
$expect = str_replace('{CONTENTTYPE}', 'multipart/alternative; boundary="alt-"', $header);
|
$expect = str_replace('{CONTENTTYPE}', 'multipart/mixed; boundary="{boundary}"', $header);
|
||||||
$expect .= '--alt-' . "\n" . 'Content-Type: text/plain; charset=UTF-8' . "\n" . 'Content-Transfer-Encoding: 8bit' . "\n\n" . $text . "\n\n";
|
$expect .= "--{boundary}\n" .
|
||||||
$expect .= '--alt-' . "\n" . 'Content-Type: text/html; charset=UTF-8' . "\n" . 'Content-Transfer-Encoding: 8bit' . "\n\n" . $html . "\n\n";
|
'Content-Type: multipart/alternative; boundary="alt-{boundary}"' . "\n\n" .
|
||||||
$expect = '<pre>' . $expect . '--alt---' . "\n\n" . '</pre>';
|
'--alt-{boundary}' . "\n" .
|
||||||
|
'Content-Type: text/plain; charset=UTF-8' . "\n" .
|
||||||
|
'Content-Transfer-Encoding: 8bit' . "\n\n" .
|
||||||
|
$text .
|
||||||
|
"\n\n" .
|
||||||
|
'--alt-{boundary}' . "\n" .
|
||||||
|
'Content-Type: text/html; charset=UTF-8' . "\n" .
|
||||||
|
'Content-Transfer-Encoding: 8bit' . "\n\n" .
|
||||||
|
$html .
|
||||||
|
"\n\n" .
|
||||||
|
'--alt-{boundary}--' . "\n\n\n" .
|
||||||
|
'--{boundary}--' . "\n";
|
||||||
|
|
||||||
|
$expect = '<pre>' . $expect . '</pre>';
|
||||||
|
|
||||||
$this->assertTrue($this->Controller->EmailTest->send('This is the body of the message'));
|
$this->assertTrue($this->Controller->EmailTest->send('This is the body of the message'));
|
||||||
$this->assertEquals(preg_replace('/alt-[a-z0-9]{32}/i', 'alt-', DebugCompTransport::$lastEmail), $this->__osFix($expect));
|
$this->assertEquals(
|
||||||
|
$this->__osFix($expect),
|
||||||
|
preg_replace('/[a-z0-9]{32}/i', '{boundary}', DebugCompTransport::$lastEmail)
|
||||||
|
);
|
||||||
|
|
||||||
$html = <<<HTMLBLOC
|
$html = <<<HTMLBLOC
|
||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
|
||||||
|
@ -441,7 +451,7 @@ HTMLBLOC;
|
||||||
|
|
||||||
$this->Controller->EmailTest->delivery = 'DebugComp';
|
$this->Controller->EmailTest->delivery = 'DebugComp';
|
||||||
|
|
||||||
$text = $html = 'This is the body of the message';
|
$text = $html = "This is the body of the message\n";
|
||||||
|
|
||||||
$this->Controller->EmailTest->sendAs = 'both';
|
$this->Controller->EmailTest->sendAs = 'both';
|
||||||
$this->assertTrue($this->Controller->EmailTest->send('This is the body of the message'));
|
$this->assertTrue($this->Controller->EmailTest->send('This is the body of the message'));
|
||||||
|
@ -740,8 +750,8 @@ HTMLBLOC;
|
||||||
$this->assertTrue($this->Controller->EmailTest->send($body));
|
$this->assertTrue($this->Controller->EmailTest->send($body));
|
||||||
$msg = DebugCompTransport::$lastEmail;
|
$msg = DebugCompTransport::$lastEmail;
|
||||||
|
|
||||||
$this->assertNotRegExp('/text\/plain/', $msg);
|
$this->assertRegExp('/text\/plain/', $msg);
|
||||||
$this->assertNotRegExp('/text\/html/', $msg);
|
$this->assertRegExp('/text\/html/', $msg);
|
||||||
$this->assertRegExp('/multipart\/alternative/', $msg);
|
$this->assertRegExp('/multipart\/alternative/', $msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -210,6 +210,22 @@ class CakeEventManagerTest extends CakeTestCase {
|
||||||
$manager->dispatch($event);
|
$manager->dispatch($event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests event dispatching using event key name
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testDispatchWithKeyName() {
|
||||||
|
$manager = new CakeEventManager;
|
||||||
|
$listener = new CakeEventTestListener;
|
||||||
|
$manager->attach(array($listener, 'listenerFunction'), 'fake.event');
|
||||||
|
$event = 'fake.event';
|
||||||
|
$manager->dispatch($event);
|
||||||
|
|
||||||
|
$expected = array('listenerFunction');
|
||||||
|
$this->assertEquals($expected, $listener->callStack);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests event dispatching with a return value
|
* Tests event dispatching with a return value
|
||||||
*
|
*
|
||||||
|
|
|
@ -868,4 +868,16 @@ class TranslateBehaviorTest extends CakeTestCase {
|
||||||
|
|
||||||
$this->assertFalse($result);
|
$this->assertFalse($result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that an exception is raised when you try to over-write the name attribute.
|
||||||
|
*
|
||||||
|
* @expectedException CakeException
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testExceptionOnNameTranslation() {
|
||||||
|
$this->loadFixtures('Translate', 'TranslatedItem');
|
||||||
|
$TestModel = new TranslatedItem();
|
||||||
|
$TestModel->bindTranslation(array('name' => 'name'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -759,7 +759,7 @@ class PostgresTest extends CakeTestCase {
|
||||||
*/
|
*/
|
||||||
function testVirtualFieldAsAConstant() {
|
function testVirtualFieldAsAConstant() {
|
||||||
$this->loadFixtures('Article', 'Comment');
|
$this->loadFixtures('Article', 'Comment');
|
||||||
$Article =& ClassRegistry::init('Article');
|
$Article = ClassRegistry::init('Article');
|
||||||
$Article->virtualFields = array(
|
$Article->virtualFields = array(
|
||||||
'empty' => "NULL",
|
'empty' => "NULL",
|
||||||
'number' => 43,
|
'number' => 43,
|
||||||
|
|
|
@ -708,6 +708,22 @@ class DboSourceTest extends CakeTestCase {
|
||||||
$Article->tablePrefix = '';
|
$Article->tablePrefix = '';
|
||||||
$result = $this->testDb->fullTableName($Article, true, false);
|
$result = $this->testDb->fullTableName($Article, true, false);
|
||||||
$this->assertEquals($result, '`with spaces`');
|
$this->assertEquals($result, '`with spaces`');
|
||||||
|
|
||||||
|
$this->loadFixtures('Article');
|
||||||
|
$Article->useTable = $Article->table = 'articles';
|
||||||
|
$Article->setDataSource('test');
|
||||||
|
$testdb = $Article->getDataSource();
|
||||||
|
$result = $testdb->fullTableName($Article, false, true);
|
||||||
|
$this->assertEquals($testdb->getSchemaName() . '.articles', $result);
|
||||||
|
|
||||||
|
// tests for empty schemaName
|
||||||
|
$noschema = ConnectionManager::create('noschema', array(
|
||||||
|
'datasource' => 'DboTestSource'
|
||||||
|
));
|
||||||
|
$Article->setDataSource('noschema');
|
||||||
|
$Article->schemaName = null;
|
||||||
|
$result = $noschema->fullTableName($Article, false, true);
|
||||||
|
$this->assertEquals('articles', $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -814,91 +814,85 @@ class ModelIntegrationTest extends BaseModelTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* test deconstruct() with time fields.
|
* data provider for time tests.
|
||||||
*
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function timeProvider() {
|
||||||
|
$db = ConnectionManager::getDataSource('test');
|
||||||
|
$now = $db->expression('NOW()');
|
||||||
|
return array(
|
||||||
|
// blank
|
||||||
|
array(
|
||||||
|
array('hour' => '', 'min' => '', 'meridian' => ''),
|
||||||
|
''
|
||||||
|
),
|
||||||
|
// missing hour
|
||||||
|
array(
|
||||||
|
array('hour' => '', 'min' => '00', 'meridian' => 'pm'),
|
||||||
|
''
|
||||||
|
),
|
||||||
|
// all blank
|
||||||
|
array(
|
||||||
|
array('hour' => '', 'min' => '', 'sec' => ''),
|
||||||
|
''
|
||||||
|
),
|
||||||
|
// set and empty merdian
|
||||||
|
array(
|
||||||
|
array('hour' => '1', 'min' => '00', 'meridian' => ''),
|
||||||
|
''
|
||||||
|
),
|
||||||
|
// midnight
|
||||||
|
array(
|
||||||
|
array('hour' => '12', 'min' => '0', 'meridian' => 'am'),
|
||||||
|
'00:00:00'
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
array('hour' => '00', 'min' => '00'),
|
||||||
|
'00:00:00'
|
||||||
|
),
|
||||||
|
// 3am
|
||||||
|
array(
|
||||||
|
array('hour' => '03', 'min' => '04', 'sec' => '04'),
|
||||||
|
'03:04:04'
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
array('hour' => '3', 'min' => '4', 'sec' => '4'),
|
||||||
|
'03:04:04'
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
array('hour' => '03', 'min' => '4', 'sec' => '4'),
|
||||||
|
'03:04:04'
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
$now,
|
||||||
|
$now
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test deconstruct with time fields.
|
||||||
|
*
|
||||||
|
* @dataProvider timeProvider
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function testDeconstructFieldsTime() {
|
public function testDeconstructFieldsTime($input, $result) {
|
||||||
$this->skipIf($this->db instanceof Sqlserver, 'This test is not compatible with SQL Server.');
|
$this->skipIf($this->db instanceof Sqlserver, 'This test is not compatible with SQL Server.');
|
||||||
|
|
||||||
$this->loadFixtures('Apple');
|
$this->loadFixtures('Apple');
|
||||||
$TestModel = new Apple();
|
$TestModel = new Apple();
|
||||||
|
|
||||||
$data = array();
|
$data = array(
|
||||||
$data['Apple']['mytime']['hour'] = '';
|
'Apple' => array(
|
||||||
$data['Apple']['mytime']['min'] = '';
|
'mytime' => $input
|
||||||
$data['Apple']['mytime']['sec'] = '';
|
)
|
||||||
|
);
|
||||||
|
|
||||||
$TestModel->data = null;
|
$TestModel->data = null;
|
||||||
$TestModel->set($data);
|
$TestModel->set($data);
|
||||||
$expected = array('Apple' => array('mytime' => ''));
|
$expected = array('Apple' => array('mytime' => $result));
|
||||||
$this->assertEquals($TestModel->data, $expected);
|
$this->assertEquals($TestModel->data, $expected);
|
||||||
|
|
||||||
$data = array();
|
|
||||||
$data['Apple']['mytime']['hour'] = '';
|
|
||||||
$data['Apple']['mytime']['min'] = '';
|
|
||||||
$data['Apple']['mytime']['meridan'] = '';
|
|
||||||
|
|
||||||
$TestModel->data = null;
|
|
||||||
$TestModel->set($data);
|
|
||||||
$expected = array('Apple' => array('mytime' => ''));
|
|
||||||
$this->assertEquals($TestModel->data, $expected, 'Empty values are not returning properly. %s');
|
|
||||||
|
|
||||||
$data = array();
|
|
||||||
$data['Apple']['mytime']['hour'] = '12';
|
|
||||||
$data['Apple']['mytime']['min'] = '0';
|
|
||||||
$data['Apple']['mytime']['meridian'] = 'am';
|
|
||||||
|
|
||||||
$TestModel->data = null;
|
|
||||||
$TestModel->set($data);
|
|
||||||
$expected = array('Apple' => array('mytime' => '00:00:00'));
|
|
||||||
$this->assertEquals($TestModel->data, $expected, 'Midnight is not returning proper values. %s');
|
|
||||||
|
|
||||||
$data = array();
|
|
||||||
$data['Apple']['mytime']['hour'] = '00';
|
|
||||||
$data['Apple']['mytime']['min'] = '00';
|
|
||||||
|
|
||||||
$TestModel->data = null;
|
|
||||||
$TestModel->set($data);
|
|
||||||
$expected = array('Apple' => array('mytime' => '00:00:00'));
|
|
||||||
$this->assertEquals($TestModel->data, $expected, 'Midnight is not returning proper values. %s');
|
|
||||||
|
|
||||||
$data = array();
|
|
||||||
$data['Apple']['mytime']['hour'] = '03';
|
|
||||||
$data['Apple']['mytime']['min'] = '04';
|
|
||||||
$data['Apple']['mytime']['sec'] = '04';
|
|
||||||
|
|
||||||
$TestModel->data = null;
|
|
||||||
$TestModel->set($data);
|
|
||||||
$expected = array('Apple' => array('mytime' => '03:04:04'));
|
|
||||||
$this->assertEquals($TestModel->data, $expected);
|
|
||||||
|
|
||||||
$data = array();
|
|
||||||
$data['Apple']['mytime']['hour'] = '3';
|
|
||||||
$data['Apple']['mytime']['min'] = '4';
|
|
||||||
$data['Apple']['mytime']['sec'] = '4';
|
|
||||||
|
|
||||||
$TestModel->data = null;
|
|
||||||
$TestModel->set($data);
|
|
||||||
$expected = array('Apple' => array('mytime' => '03:04:04'));
|
|
||||||
$this->assertEquals($TestModel->data, $expected);
|
|
||||||
|
|
||||||
$data = array();
|
|
||||||
$data['Apple']['mytime']['hour'] = '03';
|
|
||||||
$data['Apple']['mytime']['min'] = '4';
|
|
||||||
$data['Apple']['mytime']['sec'] = '4';
|
|
||||||
|
|
||||||
$TestModel->data = null;
|
|
||||||
$TestModel->set($data);
|
|
||||||
$expected = array('Apple' => array('mytime' => '03:04:04'));
|
|
||||||
$this->assertEquals($TestModel->data, $expected);
|
|
||||||
|
|
||||||
$db = ConnectionManager::getDataSource('test');
|
|
||||||
$data = array();
|
|
||||||
$data['Apple']['mytime'] = $db->expression('NOW()');
|
|
||||||
$TestModel->data = null;
|
|
||||||
$TestModel->set($data);
|
|
||||||
$this->assertEquals($TestModel->data, $data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -2987,13 +2987,21 @@ class ModelReadTest extends BaseModelTest {
|
||||||
$noAfterFindData = $noAfterFindModel->find('all');
|
$noAfterFindData = $noAfterFindModel->find('all');
|
||||||
|
|
||||||
$this->assertFalse($afterFindModel == $noAfterFindModel);
|
$this->assertFalse($afterFindModel == $noAfterFindModel);
|
||||||
// Limitation of PHP 4 and PHP 5 > 5.1.6 when comparing recursive objects
|
|
||||||
if (PHP_VERSION === '5.1.6') {
|
|
||||||
$this->assertFalse($afterFindModel != $duplicateModel);
|
|
||||||
}
|
|
||||||
$this->assertEquals($afterFindData, $noAfterFindData);
|
$this->assertEquals($afterFindData, $noAfterFindData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* find(threaded) should trigger errors whne there is no parent_id field.
|
||||||
|
*
|
||||||
|
* @expectedException PHPUnit_Framework_Error_Warning
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testFindThreadedError() {
|
||||||
|
$this->loadFixtures('Apple', 'Sample');
|
||||||
|
$Apple = new Apple();
|
||||||
|
$Apple->find('threaded');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* testFindAllThreaded method
|
* testFindAllThreaded method
|
||||||
*
|
*
|
||||||
|
|
|
@ -2770,7 +2770,7 @@ class ModelWriteTest extends BaseModelTest {
|
||||||
$this->assertEquals(count($result['Tag']), 2);
|
$this->assertEquals(count($result['Tag']), 2);
|
||||||
$this->assertEquals($result['Tag'][0]['tag'], 'tag1');
|
$this->assertEquals($result['Tag'][0]['tag'], 'tag1');
|
||||||
$this->assertEquals(count($result['Comment']), 1);
|
$this->assertEquals(count($result['Comment']), 1);
|
||||||
$this->assertEquals(count($result['Comment'][0]['comment']['Article comment']), 1);
|
$this->assertEquals(count($result['Comment'][0]['comment']), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -4098,7 +4098,7 @@ class ModelWriteTest extends BaseModelTest {
|
||||||
$this->assertEquals(count($result['Tag']), 2);
|
$this->assertEquals(count($result['Tag']), 2);
|
||||||
$this->assertEquals($result['Tag'][0]['tag'], 'tag1');
|
$this->assertEquals($result['Tag'][0]['tag'], 'tag1');
|
||||||
$this->assertEquals(count($result['Comment']), 1);
|
$this->assertEquals(count($result['Comment']), 1);
|
||||||
$this->assertEquals(count($result['Comment'][0]['comment']['Article comment']), 1);
|
$this->assertEquals(count($result['Comment'][0]['comment']), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -636,6 +636,10 @@ class CakeRequestTest extends CakeTestCase {
|
||||||
$_SERVER['HTTP_USER_AGENT'] = 'Mozilla/5.0 (Windows NT 5.1; rv:2.0b6pre) Gecko/20100902 Firefox/4.0b6pre Fennec/2.0b1pre';
|
$_SERVER['HTTP_USER_AGENT'] = 'Mozilla/5.0 (Windows NT 5.1; rv:2.0b6pre) Gecko/20100902 Firefox/4.0b6pre Fennec/2.0b1pre';
|
||||||
$this->assertTrue($request->is('mobile'));
|
$this->assertTrue($request->is('mobile'));
|
||||||
$this->assertTrue($request->isMobile());
|
$this->assertTrue($request->isMobile());
|
||||||
|
|
||||||
|
$_SERVER['HTTP_USER_AGENT'] = 'Mozilla/5.0 (compatible; MSIE 9.0; Windows Phone OS 7.5; Trident/5.0; IEMobile/9.0; SAMSUNG; OMNIA7)';
|
||||||
|
$this->assertTrue($request->is('mobile'));
|
||||||
|
$this->assertTrue($request->isMobile());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -745,6 +745,136 @@ class CakeEmailTest extends CakeTestCase {
|
||||||
$this->CakeEmail->send("Forgot to set To");
|
$this->CakeEmail->send("Forgot to set To");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test send() with no template.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testSendNoTemplateWithAttachments() {
|
||||||
|
$this->CakeEmail->transport('debug');
|
||||||
|
$this->CakeEmail->from('cake@cakephp.org');
|
||||||
|
$this->CakeEmail->to('cake@cakephp.org');
|
||||||
|
$this->CakeEmail->subject('My title');
|
||||||
|
$this->CakeEmail->emailFormat('text');
|
||||||
|
$this->CakeEmail->attachments(array(CAKE . 'basics.php'));
|
||||||
|
$result = $this->CakeEmail->send('Hello');
|
||||||
|
|
||||||
|
$boundary = $this->CakeEmail->getBoundary();
|
||||||
|
$this->assertContains('Content-Type: multipart/mixed; boundary="' . $boundary . '"', $result['headers']);
|
||||||
|
$expected = "--$boundary\r\n" .
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\r\n" .
|
||||||
|
"Content-Transfer-Encoding: 8bit\r\n" .
|
||||||
|
"\r\n" .
|
||||||
|
"Hello" .
|
||||||
|
"\r\n" .
|
||||||
|
"\r\n" .
|
||||||
|
"\r\n" .
|
||||||
|
"--$boundary\r\n" .
|
||||||
|
"Content-Type: application/octet-stream\r\n" .
|
||||||
|
"Content-Transfer-Encoding: base64\r\n" .
|
||||||
|
"Content-Disposition: attachment; filename=\"basics.php\"\r\n\r\n";
|
||||||
|
$this->assertContains($expected, $result['message']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test send() with no template as both
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testSendNoTemplateWithAttachmentsAsBoth() {
|
||||||
|
$this->CakeEmail->transport('debug');
|
||||||
|
$this->CakeEmail->from('cake@cakephp.org');
|
||||||
|
$this->CakeEmail->to('cake@cakephp.org');
|
||||||
|
$this->CakeEmail->subject('My title');
|
||||||
|
$this->CakeEmail->emailFormat('both');
|
||||||
|
$this->CakeEmail->attachments(array(CAKE . 'VERSION.txt'));
|
||||||
|
$result = $this->CakeEmail->send('Hello');
|
||||||
|
|
||||||
|
$boundary = $this->CakeEmail->getBoundary();
|
||||||
|
$this->assertContains('Content-Type: multipart/mixed; boundary="' . $boundary . '"', $result['headers']);
|
||||||
|
$expected = "--$boundary\r\n" .
|
||||||
|
"Content-Type: multipart/alternative; boundary=\"alt-$boundary\"\r\n" .
|
||||||
|
"\r\n" .
|
||||||
|
"--alt-$boundary\r\n" .
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\r\n" .
|
||||||
|
"Content-Transfer-Encoding: 8bit\r\n" .
|
||||||
|
"\r\n" .
|
||||||
|
"Hello" .
|
||||||
|
"\r\n" .
|
||||||
|
"\r\n" .
|
||||||
|
"\r\n" .
|
||||||
|
"--alt-$boundary\r\n" .
|
||||||
|
"Content-Type: text/html; charset=UTF-8\r\n" .
|
||||||
|
"Content-Transfer-Encoding: 8bit\r\n" .
|
||||||
|
"\r\n" .
|
||||||
|
"Hello" .
|
||||||
|
"\r\n" .
|
||||||
|
"\r\n" .
|
||||||
|
"\r\n" .
|
||||||
|
"--alt-{$boundary}--\r\n" .
|
||||||
|
"\r\n" .
|
||||||
|
"--$boundary\r\n" .
|
||||||
|
"Content-Type: application/octet-stream\r\n" .
|
||||||
|
"Content-Transfer-Encoding: base64\r\n" .
|
||||||
|
"Content-Disposition: attachment; filename=\"VERSION.txt\"\r\n\r\n";
|
||||||
|
$this->assertContains($expected, $result['message']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test setting inline attachments and messages.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testSendWithInlineAttachments() {
|
||||||
|
$this->CakeEmail->transport('debug');
|
||||||
|
$this->CakeEmail->from('cake@cakephp.org');
|
||||||
|
$this->CakeEmail->to('cake@cakephp.org');
|
||||||
|
$this->CakeEmail->subject('My title');
|
||||||
|
$this->CakeEmail->emailFormat('both');
|
||||||
|
$this->CakeEmail->attachments(array(
|
||||||
|
'cake.png' => array(
|
||||||
|
'file' => CAKE . 'VERSION.txt',
|
||||||
|
'contentId' => 'abc123'
|
||||||
|
)
|
||||||
|
));
|
||||||
|
$result = $this->CakeEmail->send('Hello');
|
||||||
|
|
||||||
|
$boundary = $this->CakeEmail->getBoundary();
|
||||||
|
$this->assertContains('Content-Type: multipart/mixed; boundary="' . $boundary . '"', $result['headers']);
|
||||||
|
$expected = "--$boundary\r\n" .
|
||||||
|
"Content-Type: multipart/related; boundary=\"rel-$boundary\"\r\n" .
|
||||||
|
"\r\n" .
|
||||||
|
"--rel-$boundary\r\n" .
|
||||||
|
"Content-Type: multipart/alternative; boundary=\"alt-$boundary\"\r\n" .
|
||||||
|
"\r\n" .
|
||||||
|
"--alt-$boundary\r\n" .
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\r\n" .
|
||||||
|
"Content-Transfer-Encoding: 8bit\r\n" .
|
||||||
|
"\r\n" .
|
||||||
|
"Hello" .
|
||||||
|
"\r\n" .
|
||||||
|
"\r\n" .
|
||||||
|
"\r\n" .
|
||||||
|
"--alt-$boundary\r\n" .
|
||||||
|
"Content-Type: text/html; charset=UTF-8\r\n" .
|
||||||
|
"Content-Transfer-Encoding: 8bit\r\n" .
|
||||||
|
"\r\n" .
|
||||||
|
"Hello" .
|
||||||
|
"\r\n" .
|
||||||
|
"\r\n" .
|
||||||
|
"\r\n" .
|
||||||
|
"--alt-{$boundary}--\r\n" .
|
||||||
|
"\r\n" .
|
||||||
|
"--$boundary\r\n" .
|
||||||
|
"Content-Type: application/octet-stream\r\n" .
|
||||||
|
"Content-Transfer-Encoding: base64\r\n" .
|
||||||
|
"Content-ID: <abc123>\r\n" .
|
||||||
|
"Content-Disposition: inline; filename=\"cake.png\"\r\n\r\n";
|
||||||
|
$this->assertContains($expected, $result['message']);
|
||||||
|
$this->assertContains('--rel-' . $boundary . '--', $result['message']);
|
||||||
|
$this->assertContains('--' . $boundary . '--', $result['message']);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* testSendWithLog method
|
* testSendWithLog method
|
||||||
*
|
*
|
||||||
|
@ -789,9 +919,9 @@ class CakeEmailTest extends CakeTestCase {
|
||||||
$this->CakeEmail->template('default', 'default');
|
$this->CakeEmail->template('default', 'default');
|
||||||
$result = $this->CakeEmail->send();
|
$result = $this->CakeEmail->send();
|
||||||
|
|
||||||
$this->assertTrue((bool)strpos($result['message'], 'This email was sent using the CakePHP Framework'));
|
$this->assertContains('This email was sent using the CakePHP Framework', $result['message']);
|
||||||
$this->assertTrue((bool)strpos($result['headers'], 'Message-ID: '));
|
$this->assertContains('Message-ID: ', $result['headers']);
|
||||||
$this->assertTrue((bool)strpos($result['headers'], 'To: '));
|
$this->assertContains('To: ', $result['headers']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -813,10 +943,10 @@ class CakeEmailTest extends CakeTestCase {
|
||||||
$this->CakeEmail->charset = 'ISO-2022-JP';
|
$this->CakeEmail->charset = 'ISO-2022-JP';
|
||||||
$result = $this->CakeEmail->send();
|
$result = $this->CakeEmail->send();
|
||||||
|
|
||||||
$expected = mb_convert_encoding('CakePHP Framework を使って送信したメールです。 http://cakephp.org.','ISO-2022-JP');
|
$expected = mb_convert_encoding('CakePHP Framework を使って送信したメールです。 http://cakephp.org.', 'ISO-2022-JP');
|
||||||
$this->assertTrue((bool)strpos($result['message'], $expected));
|
$this->assertContains($expected, $result['message']);
|
||||||
$this->assertTrue((bool)strpos($result['headers'], 'Message-ID: '));
|
$this->assertContains('Message-ID: ', $result['headers']);
|
||||||
$this->assertTrue((bool)strpos($result['headers'], 'To: '));
|
$this->assertContains('To: ', $result['headers']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -836,7 +966,7 @@ class CakeEmailTest extends CakeTestCase {
|
||||||
$this->CakeEmail->viewVars(array('value' => 12345));
|
$this->CakeEmail->viewVars(array('value' => 12345));
|
||||||
$result = $this->CakeEmail->send();
|
$result = $this->CakeEmail->send();
|
||||||
|
|
||||||
$this->assertTrue((bool)strpos($result['message'], 'Here is your value: 12345'));
|
$this->assertContains('Here is your value: 12345', $result['message']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -908,21 +1038,21 @@ class CakeEmailTest extends CakeTestCase {
|
||||||
$this->CakeEmail->config(array('empty'));
|
$this->CakeEmail->config(array('empty'));
|
||||||
|
|
||||||
$result = $this->CakeEmail->template('TestPlugin.test_plugin_tpl', 'default')->send();
|
$result = $this->CakeEmail->template('TestPlugin.test_plugin_tpl', 'default')->send();
|
||||||
$this->assertTrue((bool)strpos($result['message'], 'Into TestPlugin.'));
|
$this->assertContains('Into TestPlugin.', $result['message']);
|
||||||
$this->assertTrue((bool)strpos($result['message'], 'This email was sent using the CakePHP Framework'));
|
$this->assertContains('This email was sent using the CakePHP Framework', $result['message']);
|
||||||
|
|
||||||
$result = $this->CakeEmail->template('TestPlugin.test_plugin_tpl', 'TestPlugin.plug_default')->send();
|
$result = $this->CakeEmail->template('TestPlugin.test_plugin_tpl', 'TestPlugin.plug_default')->send();
|
||||||
$this->assertTrue((bool)strpos($result['message'], 'Into TestPlugin.'));
|
$this->assertContains('Into TestPlugin.', $result['message']);
|
||||||
$this->assertTrue((bool)strpos($result['message'], 'This email was sent using the TestPlugin.'));
|
$this->assertContains('This email was sent using the TestPlugin.', $result['message']);
|
||||||
|
|
||||||
$result = $this->CakeEmail->template('TestPlugin.test_plugin_tpl', 'plug_default')->send();
|
$result = $this->CakeEmail->template('TestPlugin.test_plugin_tpl', 'plug_default')->send();
|
||||||
$this->assertTrue((bool)strpos($result['message'], 'Into TestPlugin.'));
|
$this->assertContains('Into TestPlugin.', $result['message']);
|
||||||
$this->assertTrue((bool)strpos($result['message'], 'This email was sent using the TestPlugin.'));
|
$this->assertContains('This email was sent using the TestPlugin.', $result['message']);
|
||||||
|
|
||||||
$this->CakeEmail->viewVars(array('value' => 12345));
|
$this->CakeEmail->viewVars(array('value' => 12345));
|
||||||
$result = $this->CakeEmail->template('custom', 'TestPlugin.plug_default')->send();
|
$result = $this->CakeEmail->template('custom', 'TestPlugin.plug_default')->send();
|
||||||
$this->assertTrue((bool)strpos($result['message'], 'Here is your value: 12345'));
|
$this->assertContains('Here is your value: 12345', $result['message']);
|
||||||
$this->assertTrue((bool)strpos($result['message'], 'This email was sent using the TestPlugin.'));
|
$this->assertContains('This email was sent using the TestPlugin.', $result['message']);
|
||||||
|
|
||||||
$this->setExpectedException('MissingViewException');
|
$this->setExpectedException('MissingViewException');
|
||||||
$this->CakeEmail->template('test_plugin_tpl', 'plug_default')->send();
|
$this->CakeEmail->template('test_plugin_tpl', 'plug_default')->send();
|
||||||
|
@ -949,10 +1079,10 @@ class CakeEmailTest extends CakeTestCase {
|
||||||
$message = $this->CakeEmail->message();
|
$message = $this->CakeEmail->message();
|
||||||
$boundary = $this->CakeEmail->getBoundary();
|
$boundary = $this->CakeEmail->getBoundary();
|
||||||
$this->assertFalse(empty($boundary));
|
$this->assertFalse(empty($boundary));
|
||||||
$this->assertFalse(in_array('--' . $boundary, $message));
|
$this->assertContains('--' . $boundary, $message);
|
||||||
$this->assertFalse(in_array('--' . $boundary . '--', $message));
|
$this->assertContains('--' . $boundary . '--', $message);
|
||||||
$this->assertTrue(in_array('--alt-' . $boundary, $message));
|
$this->assertContains('--alt-' . $boundary, $message);
|
||||||
$this->assertTrue(in_array('--alt-' . $boundary . '--', $message));
|
$this->assertContains('--alt-' . $boundary . '--', $message);
|
||||||
|
|
||||||
$this->CakeEmail->attachments(array('fake.php' => __FILE__));
|
$this->CakeEmail->attachments(array('fake.php' => __FILE__));
|
||||||
$this->CakeEmail->send();
|
$this->CakeEmail->send();
|
||||||
|
@ -960,10 +1090,10 @@ class CakeEmailTest extends CakeTestCase {
|
||||||
$message = $this->CakeEmail->message();
|
$message = $this->CakeEmail->message();
|
||||||
$boundary = $this->CakeEmail->getBoundary();
|
$boundary = $this->CakeEmail->getBoundary();
|
||||||
$this->assertFalse(empty($boundary));
|
$this->assertFalse(empty($boundary));
|
||||||
$this->assertTrue(in_array('--' . $boundary, $message));
|
$this->assertContains('--' . $boundary, $message);
|
||||||
$this->assertTrue(in_array('--' . $boundary . '--', $message));
|
$this->assertContains('--' . $boundary . '--', $message);
|
||||||
$this->assertTrue(in_array('--alt-' . $boundary, $message));
|
$this->assertContains('--alt-' . $boundary, $message);
|
||||||
$this->assertTrue(in_array('--alt-' . $boundary . '--', $message));
|
$this->assertContains('--alt-' . $boundary . '--', $message);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -980,19 +1110,19 @@ class CakeEmailTest extends CakeTestCase {
|
||||||
$this->CakeEmail->config(array());
|
$this->CakeEmail->config(array());
|
||||||
$this->CakeEmail->attachments(array(CAKE . 'basics.php'));
|
$this->CakeEmail->attachments(array(CAKE . 'basics.php'));
|
||||||
$result = $this->CakeEmail->send('body');
|
$result = $this->CakeEmail->send('body');
|
||||||
$this->assertTrue((bool)strpos($result['message'], "Content-Type: application/octet-stream\r\nContent-Transfer-Encoding: base64\r\nContent-Disposition: attachment; filename=\"basics.php\""));
|
$this->assertContains("Content-Type: application/octet-stream\r\nContent-Transfer-Encoding: base64\r\nContent-Disposition: attachment; filename=\"basics.php\"", $result['message']);
|
||||||
|
|
||||||
$this->CakeEmail->attachments(array('my.file.txt' => CAKE . 'basics.php'));
|
$this->CakeEmail->attachments(array('my.file.txt' => CAKE . 'basics.php'));
|
||||||
$result = $this->CakeEmail->send('body');
|
$result = $this->CakeEmail->send('body');
|
||||||
$this->assertTrue((bool)strpos($result['message'], "Content-Type: application/octet-stream\r\nContent-Transfer-Encoding: base64\r\nContent-Disposition: attachment; filename=\"my.file.txt\""));
|
$this->assertContains("Content-Type: application/octet-stream\r\nContent-Transfer-Encoding: base64\r\nContent-Disposition: attachment; filename=\"my.file.txt\"", $result['message']);
|
||||||
|
|
||||||
$this->CakeEmail->attachments(array('file.txt' => array('file' => CAKE . 'basics.php', 'mimetype' => 'text/plain')));
|
$this->CakeEmail->attachments(array('file.txt' => array('file' => CAKE . 'basics.php', 'mimetype' => 'text/plain')));
|
||||||
$result = $this->CakeEmail->send('body');
|
$result = $this->CakeEmail->send('body');
|
||||||
$this->assertTrue((bool)strpos($result['message'], "Content-Type: text/plain\r\nContent-Transfer-Encoding: base64\r\nContent-Disposition: attachment; filename=\"file.txt\""));
|
$this->assertContains("Content-Type: text/plain\r\nContent-Transfer-Encoding: base64\r\nContent-Disposition: attachment; filename=\"file.txt\"", $result['message']);
|
||||||
|
|
||||||
$this->CakeEmail->attachments(array('file2.txt' => array('file' => CAKE . 'basics.php', 'mimetype' => 'text/plain', 'contentId' => 'a1b1c1')));
|
$this->CakeEmail->attachments(array('file2.txt' => array('file' => CAKE . 'basics.php', 'mimetype' => 'text/plain', 'contentId' => 'a1b1c1')));
|
||||||
$result = $this->CakeEmail->send('body');
|
$result = $this->CakeEmail->send('body');
|
||||||
$this->assertTrue((bool)strpos($result['message'], "Content-Type: text/plain\r\nContent-Transfer-Encoding: base64\r\nContent-ID: <a1b1c1>\r\nContent-Disposition: inline; filename=\"file2.txt\""));
|
$this->assertContains("Content-Type: text/plain\r\nContent-Transfer-Encoding: base64\r\nContent-ID: <a1b1c1>\r\nContent-Disposition: inline; filename=\"file2.txt\"", $result['message']);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1047,24 +1177,23 @@ class CakeEmailTest extends CakeTestCase {
|
||||||
$result = $this->CakeEmail->send();
|
$result = $this->CakeEmail->send();
|
||||||
|
|
||||||
$expected = '<p>This email was sent using the <a href="http://cakephp.org">CakePHP Framework</a></p>';
|
$expected = '<p>This email was sent using the <a href="http://cakephp.org">CakePHP Framework</a></p>';
|
||||||
$this->assertTrue((bool)strpos($this->CakeEmail->message(CakeEmail::MESSAGE_HTML), $expected));
|
$this->assertContains($expected, $this->CakeEmail->message(CakeEmail::MESSAGE_HTML));
|
||||||
|
|
||||||
$expected = 'This email was sent using the CakePHP Framework, http://cakephp.org.';
|
$expected = 'This email was sent using the CakePHP Framework, http://cakephp.org.';
|
||||||
$this->assertTrue((bool)strpos($this->CakeEmail->message(CakeEmail::MESSAGE_TEXT), $expected));
|
$this->assertContains($expected, $this->CakeEmail->message(CakeEmail::MESSAGE_TEXT));
|
||||||
|
|
||||||
$message = $this->CakeEmail->message();
|
$message = $this->CakeEmail->message();
|
||||||
$this->assertTrue(in_array('Content-Type: text/plain; charset=UTF-8', $message));
|
$this->assertContains('Content-Type: text/plain; charset=UTF-8', $message);
|
||||||
$this->assertTrue(in_array('Content-Type: text/html; charset=UTF-8', $message));
|
$this->assertContains('Content-Type: text/html; charset=UTF-8', $message);
|
||||||
|
|
||||||
// UTF-8 is 8bit
|
// UTF-8 is 8bit
|
||||||
$this->assertTrue($this->checkContentTransferEncoding($message, '8bit'));
|
$this->assertTrue($this->checkContentTransferEncoding($message, '8bit'));
|
||||||
|
|
||||||
|
|
||||||
$this->CakeEmail->charset = 'ISO-2022-JP';
|
$this->CakeEmail->charset = 'ISO-2022-JP';
|
||||||
$this->CakeEmail->send();
|
$this->CakeEmail->send();
|
||||||
$message = $this->CakeEmail->message();
|
$message = $this->CakeEmail->message();
|
||||||
$this->assertTrue(in_array('Content-Type: text/plain; charset=ISO-2022-JP', $message));
|
$this->assertContains('Content-Type: text/plain; charset=ISO-2022-JP', $message);
|
||||||
$this->assertTrue(in_array('Content-Type: text/html; charset=ISO-2022-JP', $message));
|
$this->assertContains('Content-Type: text/html; charset=ISO-2022-JP', $message);
|
||||||
|
|
||||||
// ISO-2022-JP is 7bit
|
// ISO-2022-JP is 7bit
|
||||||
$this->assertTrue($this->checkContentTransferEncoding($message, '7bit'));
|
$this->assertTrue($this->checkContentTransferEncoding($message, '7bit'));
|
||||||
|
|
|
@ -214,6 +214,7 @@ class SmtpTransportTest extends CakeTestCase {
|
||||||
$this->getMock('CakeEmail', array('message'), array(), 'SmtpCakeEmail');
|
$this->getMock('CakeEmail', array('message'), array(), 'SmtpCakeEmail');
|
||||||
$email = new SmtpCakeEmail();
|
$email = new SmtpCakeEmail();
|
||||||
$email->from('noreply@cakephp.org', 'CakePHP Test');
|
$email->from('noreply@cakephp.org', 'CakePHP Test');
|
||||||
|
$email->returnPath('pleasereply@cakephp.org', 'CakePHP Return');
|
||||||
$email->to('cake@cakephp.org', 'CakePHP');
|
$email->to('cake@cakephp.org', 'CakePHP');
|
||||||
$email->cc(array('mark@cakephp.org' => 'Mark Story', 'juan@cakephp.org' => 'Juan Basso'));
|
$email->cc(array('mark@cakephp.org' => 'Mark Story', 'juan@cakephp.org' => 'Juan Basso'));
|
||||||
$email->bcc('phpnut@cakephp.org');
|
$email->bcc('phpnut@cakephp.org');
|
||||||
|
@ -222,6 +223,7 @@ class SmtpTransportTest extends CakeTestCase {
|
||||||
$email->expects($this->any())->method('message')->will($this->returnValue(array('First Line', 'Second Line', '')));
|
$email->expects($this->any())->method('message')->will($this->returnValue(array('First Line', 'Second Line', '')));
|
||||||
|
|
||||||
$data = "From: CakePHP Test <noreply@cakephp.org>\r\n";
|
$data = "From: CakePHP Test <noreply@cakephp.org>\r\n";
|
||||||
|
$data .= "Return-Path: CakePHP Return <pleasereply@cakephp.org>\r\n";
|
||||||
$data .= "To: CakePHP <cake@cakephp.org>\r\n";
|
$data .= "To: CakePHP <cake@cakephp.org>\r\n";
|
||||||
$data .= "Cc: Mark Story <mark@cakephp.org>, Juan Basso <juan@cakephp.org>\r\n";
|
$data .= "Cc: Mark Story <mark@cakephp.org>, Juan Basso <juan@cakephp.org>\r\n";
|
||||||
$data .= "X-Mailer: CakePHP Email\r\n";
|
$data .= "X-Mailer: CakePHP Email\r\n";
|
||||||
|
|
|
@ -2454,6 +2454,37 @@ class RouterTest extends CakeTestCase {
|
||||||
$this->assertFalse($result);
|
$this->assertFalse($result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests resourceMap as getter and setter.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testResourceMap() {
|
||||||
|
$default = Router::resourceMap();
|
||||||
|
$exepcted = array(
|
||||||
|
array('action' => 'index', 'method' => 'GET', 'id' => false),
|
||||||
|
array('action' => 'view', 'method' => 'GET', 'id' => true),
|
||||||
|
array('action' => 'add', 'method' => 'POST', 'id' => false),
|
||||||
|
array('action' => 'edit', 'method' => 'PUT', 'id' => true),
|
||||||
|
array('action' => 'delete', 'method' => 'DELETE', 'id' => true),
|
||||||
|
array('action' => 'edit', 'method' => 'POST', 'id' => true)
|
||||||
|
);
|
||||||
|
$this->assertEquals($default, $exepcted);
|
||||||
|
|
||||||
|
$custom = array(
|
||||||
|
array('action' => 'index', 'method' => 'GET', 'id' => false),
|
||||||
|
array('action' => 'view', 'method' => 'GET', 'id' => true),
|
||||||
|
array('action' => 'add', 'method' => 'POST', 'id' => false),
|
||||||
|
array('action' => 'edit', 'method' => 'PUT', 'id' => true),
|
||||||
|
array('action' => 'delete', 'method' => 'DELETE', 'id' => true),
|
||||||
|
array('action' => 'update', 'method' => 'POST', 'id' => true)
|
||||||
|
);
|
||||||
|
Router::resourceMap($custom);
|
||||||
|
$this->assertEquals($custom, Router::resourceMap());
|
||||||
|
|
||||||
|
Router::resourceMap($default);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* test setting redirect routes
|
* test setting redirect routes
|
||||||
*
|
*
|
||||||
|
|
|
@ -1562,6 +1562,10 @@ class HtmlHelperTest extends CakeTestCase {
|
||||||
}
|
}
|
||||||
$this->assertEquals($helper->parseAttributes(array('compact')), ' compact="compact"');
|
$this->assertEquals($helper->parseAttributes(array('compact')), ' compact="compact"');
|
||||||
|
|
||||||
|
$attrs = array('class' => array('foo', 'bar'));
|
||||||
|
$expected = ' class="foo bar"';
|
||||||
|
$this->assertEquals(' class="foo bar"', $helper->parseAttributes($attrs));
|
||||||
|
|
||||||
$helper = new Html5TestHelper($this->View);
|
$helper = new Html5TestHelper($this->View);
|
||||||
$expected = ' require';
|
$expected = ' require';
|
||||||
$this->assertEquals($helper->parseAttributes(array('require')), $expected);
|
$this->assertEquals($helper->parseAttributes(array('require')), $expected);
|
||||||
|
|
|
@ -60,7 +60,7 @@ class TextHelperTest extends CakeTestCase {
|
||||||
$text5 = '0<b>1<i>2<span class="myclass">3</span>4<u>5</u>6</i>7</b>8<b>9</b>0';
|
$text5 = '0<b>1<i>2<span class="myclass">3</span>4<u>5</u>6</i>7</b>8<b>9</b>0';
|
||||||
$text6 = '<p><strong>Extra dates have been announced for this year\'s tour.</strong></p><p>Tickets for the new shows in</p>';
|
$text6 = '<p><strong>Extra dates have been announced for this year\'s tour.</strong></p><p>Tickets for the new shows in</p>';
|
||||||
$text7 = 'El moño está en el lugar correcto. Eso fue lo que dijo la niña, ¿habrá dicho la verdad?';
|
$text7 = 'El moño está en el lugar correcto. Eso fue lo que dijo la niña, ¿habrá dicho la verdad?';
|
||||||
$text8 = 'Vive la R'.chr(195).chr(169).'publique de France';
|
$text8 = 'Vive la R' . chr(195) . chr(169) . 'publique de France';
|
||||||
$text9 = 'НОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыь';
|
$text9 = 'НОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыь';
|
||||||
|
|
||||||
$this->assertSame($this->Text->truncate($text1, 15), 'The quick br...');
|
$this->assertSame($this->Text->truncate($text1, 15), 'The quick br...');
|
||||||
|
@ -86,6 +86,51 @@ class TextHelperTest extends CakeTestCase {
|
||||||
$this->assertSame($this->Text->truncate($text7, 15), 'El moño está...');
|
$this->assertSame($this->Text->truncate($text7, 15), 'El moño está...');
|
||||||
$this->assertSame($this->Text->truncate($text8, 15), 'Vive la R'.chr(195).chr(169).'pu...');
|
$this->assertSame($this->Text->truncate($text8, 15), 'Vive la R'.chr(195).chr(169).'pu...');
|
||||||
$this->assertSame($this->Text->truncate($text9, 10), 'НОПРСТУ...');
|
$this->assertSame($this->Text->truncate($text9, 10), 'НОПРСТУ...');
|
||||||
|
|
||||||
|
$text = '<p><span style="font-size: medium;"><a>Iamatestwithnospacesandhtml</a></span></p>';
|
||||||
|
$result = $this->Text->truncate($text, 10, array(
|
||||||
|
'ending' => '...',
|
||||||
|
'exact' => false,
|
||||||
|
'html' => true
|
||||||
|
));
|
||||||
|
$expected = '<p><span style="font-size: medium;"><a>...</a></span></p>';
|
||||||
|
$this->assertEquals($expected, $result);
|
||||||
|
|
||||||
|
$text = '<p><span style="font-size: medium;">El biógrafo de Steve Jobs, Walter
|
||||||
|
Isaacson, explica porqué Jobs le pidió que le hiciera su biografía en
|
||||||
|
este artículo de El País.</span></p>
|
||||||
|
<p><span style="font-size: medium;"><span style="font-size:
|
||||||
|
large;">Por qué Steve era distinto.</span></span></p>
|
||||||
|
<p><span style="font-size: medium;"><a href="http://www.elpais.com/
|
||||||
|
articulo/primer/plano/Steve/era/distinto/elpepueconeg/
|
||||||
|
20111009elpneglse_4/Tes">http://www.elpais.com/articulo/primer/plano/
|
||||||
|
Steve/era/distinto/elpepueconeg/20111009elpneglse_4/Tes</a></span></p>
|
||||||
|
<p><span style="font-size: medium;">Ya se ha publicado la biografía de
|
||||||
|
Steve Jobs escrita por Walter Isaacson "<strong>Steve Jobs by Walter
|
||||||
|
Isaacson</strong>", aquí os dejamos la dirección de amazon donde
|
||||||
|
podeís adquirirla.</span></p>
|
||||||
|
<p><span style="font-size: medium;"><a>http://www.amazon.com/Steve-
|
||||||
|
Jobs-Walter-Isaacson/dp/1451648537</a></span></p>';
|
||||||
|
$result = $this->Text->truncate($text, 500, array(
|
||||||
|
'ending' => '... ',
|
||||||
|
'exact' => false,
|
||||||
|
'html' => true
|
||||||
|
));
|
||||||
|
$expected = '<p><span style="font-size: medium;">El biógrafo de Steve Jobs, Walter
|
||||||
|
Isaacson, explica porqué Jobs le pidió que le hiciera su biografía en
|
||||||
|
este artículo de El País.</span></p>
|
||||||
|
<p><span style="font-size: medium;"><span style="font-size:
|
||||||
|
large;">Por qué Steve era distinto.</span></span></p>
|
||||||
|
<p><span style="font-size: medium;"><a href="http://www.elpais.com/
|
||||||
|
articulo/primer/plano/Steve/era/distinto/elpepueconeg/
|
||||||
|
20111009elpneglse_4/Tes">http://www.elpais.com/articulo/primer/plano/
|
||||||
|
Steve/era/distinto/elpepueconeg/20111009elpneglse_4/Tes</a></span></p>
|
||||||
|
<p><span style="font-size: medium;">Ya se ha publicado la biografía de
|
||||||
|
Steve Jobs escrita por Walter Isaacson "<strong>Steve Jobs by Walter
|
||||||
|
Isaacson</strong>", aquí os dejamos la dirección de amazon donde
|
||||||
|
podeís adquirirla.</span></p>
|
||||||
|
<p><span style="font-size: medium;"><a>... </a></span></p>';
|
||||||
|
$this->assertEquals($expected, $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -671,7 +671,10 @@ class Debugger {
|
||||||
$data += $defaults;
|
$data += $defaults;
|
||||||
|
|
||||||
$files = $this->trace(array('start' => $data['start'], 'format' => 'points'));
|
$files = $this->trace(array('start' => $data['start'], 'format' => 'points'));
|
||||||
$code = $this->excerpt($files[0]['file'], $files[0]['line'] - 1, 1);
|
$code = '';
|
||||||
|
if (isset($files[0]['file'])) {
|
||||||
|
$code = $this->excerpt($files[0]['file'], $files[0]['line'] - 1, 1);
|
||||||
|
}
|
||||||
$trace = $this->trace(array('start' => $data['start'], 'depth' => '20'));
|
$trace = $this->trace(array('start' => $data['start'], 'depth' => '20'));
|
||||||
$insertOpts = array('before' => '{:', 'after' => '}');
|
$insertOpts = array('before' => '{:', 'after' => '}');
|
||||||
$context = array();
|
$context = array();
|
||||||
|
|
|
@ -109,7 +109,8 @@ abstract class ObjectCollection {
|
||||||
$options[$opt] = $event->{$opt};
|
$options[$opt] = $event->{$opt};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$callback = array_pop(explode('.', $event->name()));
|
$parts = explode('.', $event->name());
|
||||||
|
$callback = array_pop($parts);
|
||||||
}
|
}
|
||||||
$options = array_merge(
|
$options = array_merge(
|
||||||
array(
|
array(
|
||||||
|
|
|
@ -671,7 +671,7 @@ class Set {
|
||||||
if (is_numeric($key) && intval($key) > 0 || $key === '0') {
|
if (is_numeric($key) && intval($key) > 0 || $key === '0') {
|
||||||
$key = intval($key);
|
$key = intval($key);
|
||||||
}
|
}
|
||||||
if ($i === $count - 1) {
|
if ($i === $count - 1 && is_array($_list)) {
|
||||||
$_list[$key] = $data;
|
$_list[$key] = $data;
|
||||||
} else {
|
} else {
|
||||||
if (!isset($_list[$key])) {
|
if (!isset($_list[$key])) {
|
||||||
|
@ -679,6 +679,9 @@ class Set {
|
||||||
}
|
}
|
||||||
$_list =& $_list[$key];
|
$_list =& $_list[$key];
|
||||||
}
|
}
|
||||||
|
if (!is_array($_list)) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return $list;
|
return $list;
|
||||||
}
|
}
|
||||||
|
|
|
@ -356,7 +356,7 @@ class Helper extends Object {
|
||||||
* @param string $insertBefore String to be inserted before options.
|
* @param string $insertBefore String to be inserted before options.
|
||||||
* @param string $insertAfter String to be inserted after options.
|
* @param string $insertAfter String to be inserted after options.
|
||||||
* @return string Composed attributes.
|
* @return string Composed attributes.
|
||||||
* @deprecated This method has been moved to HtmlHelper
|
* @deprecated This method will be moved to HtmlHelper in 3.0
|
||||||
*/
|
*/
|
||||||
protected function _parseAttributes($options, $exclude = null, $insertBefore = ' ', $insertAfter = null) {
|
protected function _parseAttributes($options, $exclude = null, $insertBefore = ' ', $insertAfter = null) {
|
||||||
if (!is_string($options)) {
|
if (!is_string($options)) {
|
||||||
|
@ -390,12 +390,12 @@ class Helper extends Object {
|
||||||
* @param string $value The value of the attribute to create.
|
* @param string $value The value of the attribute to create.
|
||||||
* @param boolean $escape Define if the value must be escaped
|
* @param boolean $escape Define if the value must be escaped
|
||||||
* @return string The composed attribute.
|
* @return string The composed attribute.
|
||||||
* @deprecated This method has been moved to HtmlHelper
|
* @deprecated This method will be moved to HtmlHelper in 3.0
|
||||||
*/
|
*/
|
||||||
protected function _formatAttribute($key, $value, $escape = true) {
|
protected function _formatAttribute($key, $value, $escape = true) {
|
||||||
$attribute = '';
|
$attribute = '';
|
||||||
if (is_array($value)) {
|
if (is_array($value)) {
|
||||||
$value = '';
|
$value = implode(' ' , $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_numeric($key)) {
|
if (is_numeric($key)) {
|
||||||
|
@ -672,9 +672,6 @@ class Helper extends Object {
|
||||||
$options = $this->_name($options);
|
$options = $this->_name($options);
|
||||||
$options = $this->value($options);
|
$options = $this->value($options);
|
||||||
$options = $this->domId($options);
|
$options = $this->domId($options);
|
||||||
if ($this->tagIsInvalid() !== false) {
|
|
||||||
$options = $this->addClass($options, 'form-error');
|
|
||||||
}
|
|
||||||
return $options;
|
return $options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -737,8 +737,48 @@ class FormHelper extends AppHelper {
|
||||||
* Returns a formatted LABEL element for HTML FORMs. Will automatically generate
|
* Returns a formatted LABEL element for HTML FORMs. Will automatically generate
|
||||||
* a for attribute if one is not provided.
|
* a for attribute if one is not provided.
|
||||||
*
|
*
|
||||||
|
* ### Options
|
||||||
|
*
|
||||||
|
* - `for` - Set the for attribute, if its not defined the for attribute
|
||||||
|
* will be generated from the $fieldName parameter using
|
||||||
|
* FormHelper::domId().
|
||||||
|
*
|
||||||
|
* Examples:
|
||||||
|
*
|
||||||
|
* The text and for attribute are generated off of the fieldname
|
||||||
|
*
|
||||||
|
* {{{
|
||||||
|
* echo $this->Form->label('Post.published');
|
||||||
|
* <label for="PostPublished">Published</label>
|
||||||
|
* }}}
|
||||||
|
*
|
||||||
|
* Custom text:
|
||||||
|
*
|
||||||
|
* {{{
|
||||||
|
* echo $this->Form->label('Post.published', 'Publish');
|
||||||
|
* <label for="PostPublished">Publish</label>
|
||||||
|
* }}}
|
||||||
|
*
|
||||||
|
* Custom class name:
|
||||||
|
*
|
||||||
|
* {{{
|
||||||
|
* echo $this->Form->label('Post.published', 'Publish', 'required');
|
||||||
|
* <label for="PostPublished" class="required">Publish</label>
|
||||||
|
* }}}
|
||||||
|
*
|
||||||
|
* Custom attributes:
|
||||||
|
*
|
||||||
|
* {{{
|
||||||
|
* echo $this->Form->label('Post.published', 'Publish', array(
|
||||||
|
* 'for' => 'post-publish'
|
||||||
|
* ));
|
||||||
|
* <label for="post-publish">Publish</label>
|
||||||
|
* }}}
|
||||||
|
*
|
||||||
* @param string $fieldName This should be "Modelname.fieldname"
|
* @param string $fieldName This should be "Modelname.fieldname"
|
||||||
* @param string $text Text that will appear in the label field.
|
* @param string $text Text that will appear in the label field. If
|
||||||
|
* $text is left undefined the text will be inflected from the
|
||||||
|
* fieldName.
|
||||||
* @param mixed $options An array of HTML attributes, or a string, to be used as a class name.
|
* @param mixed $options An array of HTML attributes, or a string, to be used as a class name.
|
||||||
* @return string The formatted LABEL element
|
* @return string The formatted LABEL element
|
||||||
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#FormHelper::label
|
* @link http://book.cakephp.org/2.0/en/core-libraries/helpers/form.html#FormHelper::label
|
||||||
|
@ -2534,6 +2574,9 @@ class FormHelper extends AppHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
$result = parent::_initInputField($field, $options);
|
$result = parent::_initInputField($field, $options);
|
||||||
|
if ($this->tagIsInvalid() !== false) {
|
||||||
|
$result = $this->addClass($result, 'form-error');
|
||||||
|
}
|
||||||
if (!empty($result['disabled']) || $secure === self::SECURE_SKIP) {
|
if (!empty($result['disabled']) || $secure === self::SECURE_SKIP) {
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1071,93 +1071,4 @@ class HtmlHelper extends AppHelper {
|
||||||
return $configs;
|
return $configs;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a space-delimited string with items of the $options array. If a
|
|
||||||
* key of $options array happens to be one of:
|
|
||||||
*
|
|
||||||
* - 'compact'
|
|
||||||
* - 'checked'
|
|
||||||
* - 'declare'
|
|
||||||
* - 'readonly'
|
|
||||||
* - 'disabled'
|
|
||||||
* - 'selected'
|
|
||||||
* - 'defer'
|
|
||||||
* - 'ismap'
|
|
||||||
* - 'nohref'
|
|
||||||
* - 'noshade'
|
|
||||||
* - 'nowrap'
|
|
||||||
* - 'multiple'
|
|
||||||
* - 'noresize'
|
|
||||||
*
|
|
||||||
* And its value is one of:
|
|
||||||
*
|
|
||||||
* - '1' (string)
|
|
||||||
* - 1 (integer)
|
|
||||||
* - true (boolean)
|
|
||||||
* - 'true' (string)
|
|
||||||
*
|
|
||||||
* Then the value will be reset to be identical with key's name.
|
|
||||||
* If the value is not one of these 3, the parameter is not output.
|
|
||||||
*
|
|
||||||
* 'escape' is a special option in that it controls the conversion of
|
|
||||||
* attributes to their html-entity encoded equivalents. Set to false to disable html-encoding.
|
|
||||||
*
|
|
||||||
* If value for any option key is set to `null` or `false`, that option will be excluded from output.
|
|
||||||
*
|
|
||||||
* @param array $options Array of options.
|
|
||||||
* @param array $exclude Array of options to be excluded, the options here will not be part of the return.
|
|
||||||
* @param string $insertBefore String to be inserted before options.
|
|
||||||
* @param string $insertAfter String to be inserted after options.
|
|
||||||
* @return string Composed attributes.
|
|
||||||
*/
|
|
||||||
protected function _parseAttributes($options, $exclude = null, $insertBefore = ' ', $insertAfter = null) {
|
|
||||||
if (is_array($options)) {
|
|
||||||
$options = array_merge(array('escape' => true), $options);
|
|
||||||
|
|
||||||
if (!is_array($exclude)) {
|
|
||||||
$exclude = array();
|
|
||||||
}
|
|
||||||
$filtered = array_diff_key($options, array_merge(array_flip($exclude), array('escape' => true)));
|
|
||||||
$escape = $options['escape'];
|
|
||||||
$attributes = array();
|
|
||||||
|
|
||||||
foreach ($filtered as $key => $value) {
|
|
||||||
if ($value !== false && $value !== null) {
|
|
||||||
$attributes[] = $this->_formatAttribute($key, $value, $escape);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$out = implode(' ', $attributes);
|
|
||||||
} else {
|
|
||||||
$out = $options;
|
|
||||||
}
|
|
||||||
return $out ? $insertBefore . $out . $insertAfter : '';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Formats an individual attribute, and returns the string value of the composed attribute.
|
|
||||||
* Works with minimized attributes that have the same value as their name such as 'disabled' and 'checked'
|
|
||||||
*
|
|
||||||
* @param string $key The name of the attribute to create
|
|
||||||
* @param string $value The value of the attribute to create.
|
|
||||||
* @param boolean $escape Define if the value must be escaped
|
|
||||||
* @return string The composed attribute.
|
|
||||||
*/
|
|
||||||
protected function _formatAttribute($key, $value, $escape = true) {
|
|
||||||
$attribute = '';
|
|
||||||
if (is_array($value)) {
|
|
||||||
$value = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_numeric($key)) {
|
|
||||||
$attribute = sprintf($this->_minimizedAttributeFormat, $value, $value);
|
|
||||||
} elseif (in_array($key, $this->_minimizedAttributes)) {
|
|
||||||
if ($value === 1 || $value === true || $value === 'true' || $value === '1' || $value == $key) {
|
|
||||||
$attribute = sprintf($this->_minimizedAttributeFormat, $key, $key);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$attribute = sprintf($this->_attributeFormat, $key, ($escape ? h($value) : $value));
|
|
||||||
}
|
|
||||||
return $attribute;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -323,20 +323,32 @@ class TextHelper extends AppHelper {
|
||||||
}
|
}
|
||||||
if (!$exact) {
|
if (!$exact) {
|
||||||
$spacepos = mb_strrpos($truncate, ' ');
|
$spacepos = mb_strrpos($truncate, ' ');
|
||||||
if (isset($spacepos)) {
|
if ($html) {
|
||||||
if ($html) {
|
$truncateCheck = mb_substr($truncate, 0, $spacepos);
|
||||||
$bits = mb_substr($truncate, $spacepos);
|
$lastOpenTag = mb_strrpos($truncateCheck, '<');
|
||||||
preg_match_all('/<\/([a-z]+)>/', $bits, $droppedTags, PREG_SET_ORDER);
|
$lastCloseTag = mb_strrpos($truncateCheck, '>');
|
||||||
if (!empty($droppedTags)) {
|
if ($lastOpenTag > $lastCloseTag) {
|
||||||
|
preg_match_all('/<[\w]+[^>]*>/s', $truncate, $lastTagMatches);
|
||||||
|
$lastTag = array_pop($lastTagMatches[0]);
|
||||||
|
$spacepos = mb_strrpos($truncate, $lastTag) + mb_strlen($lastTag);
|
||||||
|
}
|
||||||
|
$bits = mb_substr($truncate, $spacepos);
|
||||||
|
preg_match_all('/<\/([a-z]+)>/', $bits, $droppedTags, PREG_SET_ORDER);
|
||||||
|
if (!empty($droppedTags)) {
|
||||||
|
if (!empty($openTags)) {
|
||||||
foreach ($droppedTags as $closingTag) {
|
foreach ($droppedTags as $closingTag) {
|
||||||
if (!in_array($closingTag[1], $openTags)) {
|
if (!in_array($closingTag[1], $openTags)) {
|
||||||
array_unshift($openTags, $closingTag[1]);
|
array_unshift($openTags, $closingTag[1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
foreach ($droppedTags as $closingTag) {
|
||||||
|
array_push($openTags, $closingTag[1]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$truncate = mb_substr($truncate, 0, $spacepos);
|
|
||||||
}
|
}
|
||||||
|
$truncate = mb_substr($truncate, 0, $spacepos);
|
||||||
}
|
}
|
||||||
$truncate .= $ending;
|
$truncate .= $ending;
|
||||||
|
|
||||||
|
|
|
@ -465,7 +465,7 @@ class View extends Object {
|
||||||
* the 'meta', 'css', and 'script' blocks. They are appended in that order.
|
* the 'meta', 'css', and 'script' blocks. They are appended in that order.
|
||||||
*
|
*
|
||||||
* Deprecated features:
|
* Deprecated features:
|
||||||
*
|
*
|
||||||
* - `$scripts_for_layout` is deprecated and will be removed in CakePHP 3.0.
|
* - `$scripts_for_layout` is deprecated and will be removed in CakePHP 3.0.
|
||||||
* Use the block features instead. `meta`, `css` and `script` will be populated
|
* Use the block features instead. `meta`, `css` and `script` will be populated
|
||||||
* by the matching methods on HtmlHelper.
|
* by the matching methods on HtmlHelper.
|
||||||
|
@ -493,7 +493,7 @@ class View extends Object {
|
||||||
$this->getEventManager()->dispatch(new CakeEvent('View.beforeLayout', $this, array($layoutFileName)));
|
$this->getEventManager()->dispatch(new CakeEvent('View.beforeLayout', $this, array($layoutFileName)));
|
||||||
|
|
||||||
$scripts = implode("\n\t", $this->_scripts);
|
$scripts = implode("\n\t", $this->_scripts);
|
||||||
$scripts .= $this->get('meta') . $this->get('css') . $this->get('script');
|
$scripts .= $this->Blocks->get('meta') . $this->Blocks->get('css') . $this->Blocks->get('script');
|
||||||
|
|
||||||
$this->viewVars = array_merge($this->viewVars, array(
|
$this->viewVars = array_merge($this->viewVars, array(
|
||||||
'content_for_layout' => $content,
|
'content_for_layout' => $content,
|
||||||
|
@ -600,7 +600,7 @@ class View extends Object {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Append to an existing or new block. Appending to a new
|
* Append to an existing or new block. Appending to a new
|
||||||
* block will create the block.
|
* block will create the block.
|
||||||
*
|
*
|
||||||
* @param string $name Name of the block
|
* @param string $name Name of the block
|
||||||
|
@ -650,7 +650,7 @@ class View extends Object {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides view or element extension/inheritance. Views can extends a
|
* Provides view or element extension/inheritance. Views can extends a
|
||||||
* parent view and populate blocks in the parent template.
|
* parent view and populate blocks in the parent template.
|
||||||
*
|
*
|
||||||
* @param string $name The view or element to 'extend' the current one with.
|
* @param string $name The view or element to 'extend' the current one with.
|
||||||
|
@ -668,7 +668,7 @@ class View extends Object {
|
||||||
case self::TYPE_LAYOUT:
|
case self::TYPE_LAYOUT:
|
||||||
$parent = $this->_getLayoutFileName($name);
|
$parent = $this->_getLayoutFileName($name);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
if ($parent == $this->_current) {
|
if ($parent == $this->_current) {
|
||||||
throw new LogicException(__d('cake_dev', 'You cannot have views extend themselves.'));
|
throw new LogicException(__d('cake_dev', 'You cannot have views extend themselves.'));
|
||||||
|
@ -775,7 +775,7 @@ class View extends Object {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Magic accessor for deprecated attributes.
|
* Magic accessor for deprecated attributes.
|
||||||
*
|
*
|
||||||
* @param string $name Name of the attribute to set.
|
* @param string $name Name of the attribute to set.
|
||||||
* @param string $value Value of the attribute to set.
|
* @param string $value Value of the attribute to set.
|
||||||
* @return mixed
|
* @return mixed
|
||||||
|
@ -789,6 +789,16 @@ class View extends Object {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Magic isset check for deprecated attributes.
|
||||||
|
*
|
||||||
|
* @param string $name Name of the attribute to check.
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
public function __isset($name) {
|
||||||
|
return isset($this->name);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interact with the HelperCollection to load all the helpers.
|
* Interact with the HelperCollection to load all the helpers.
|
||||||
*
|
*
|
||||||
|
@ -817,12 +827,10 @@ class View extends Object {
|
||||||
$data = $this->viewVars;
|
$data = $this->viewVars;
|
||||||
}
|
}
|
||||||
$this->_current = $viewFile;
|
$this->_current = $viewFile;
|
||||||
|
$initialBlocks = count($this->Blocks->unclosed());
|
||||||
|
|
||||||
$this->getEventManager()->dispatch(new CakeEvent('View.beforeRenderFile', $this, array($viewFile)));
|
$this->getEventManager()->dispatch(new CakeEvent('View.beforeRenderFile', $this, array($viewFile)));
|
||||||
$content = $this->_evaluate($viewFile, $data);
|
$content = $this->_evaluate($viewFile, $data);
|
||||||
if ($this->Blocks->active()) {
|
|
||||||
throw new CakeException(__d('cake_dev', 'The "%s" block was left open.', $this->Blocks->active()));
|
|
||||||
}
|
|
||||||
$afterEvent = new CakeEvent('View.afterRenderFile', $this, array($viewFile, $content));
|
$afterEvent = new CakeEvent('View.afterRenderFile', $this, array($viewFile, $content));
|
||||||
//TODO: For BC puporses, set extra info in the event object. Remove when appropriate
|
//TODO: For BC puporses, set extra info in the event object. Remove when appropriate
|
||||||
$afterEvent->modParams = 1;
|
$afterEvent->modParams = 1;
|
||||||
|
@ -833,11 +841,16 @@ class View extends Object {
|
||||||
$this->_stack[] = $this->fetch('content');
|
$this->_stack[] = $this->fetch('content');
|
||||||
$this->assign('content', $content);
|
$this->assign('content', $content);
|
||||||
|
|
||||||
$content = $this->_render($this->_parents[$viewFile], $data);
|
$content = $this->_render($this->_parents[$viewFile]);
|
||||||
|
|
||||||
$this->assign('content', array_pop($this->_stack));
|
$this->assign('content', array_pop($this->_stack));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$remainingBlocks = count($this->Blocks->unclosed());
|
||||||
|
|
||||||
|
if ($initialBlocks !== $remainingBlocks) {
|
||||||
|
throw new CakeException(__d('cake_dev', 'The "%s" block was left open. Blocks are not allowed to cross files.', $this->Blocks->active()));
|
||||||
|
}
|
||||||
|
|
||||||
return $content;
|
return $content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -845,7 +858,7 @@ class View extends Object {
|
||||||
* Sandbox method to evaluate a template / view script in.
|
* Sandbox method to evaluate a template / view script in.
|
||||||
*
|
*
|
||||||
* @param string $___viewFn Filename of the view
|
* @param string $___viewFn Filename of the view
|
||||||
* @param array $___dataForView Data to include in rendered view.
|
* @param array $___dataForView Data to include in rendered view.
|
||||||
* If empty the current View::$viewVars will be used.
|
* If empty the current View::$viewVars will be used.
|
||||||
* @return string Rendered output
|
* @return string Rendered output
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -145,4 +145,13 @@ class ViewBlock {
|
||||||
public function active() {
|
public function active() {
|
||||||
return end($this->_active);
|
return end($this->_active);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the names of the unclosed/active blocks.
|
||||||
|
*
|
||||||
|
* @return array An array of unclosed blocks.
|
||||||
|
*/
|
||||||
|
public function unclosed() {
|
||||||
|
return $this->_active;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue