Browse Source

Merge pull request #4529 from cakephp/3.0-split-utility

3.0 split utility
José Lorenzo Rodríguez 11 years ago
parent
commit
b8a6491b41

+ 2 - 1
composer.json

@@ -42,6 +42,7 @@
 	"replace": {
 		"cakephp/collection": "self.version",
 		"cakephp/event": "self.version",
-		"cakephp/validation": "self.version"
+		"cakephp/validation": "self.version",
+		"cakephp/utility": "self.version"
 	}
 }

+ 88 - 0
src/Utility/README.md

@@ -0,0 +1,88 @@
+# CakePHP Utility Classes
+
+This library provides a range of utility classes that are used throughout the CakePHP framework
+
+## What's in the toolbox?
+
+### Hash
+
+A ``Hash`` (as in PHP arrays) class, capable of extracting data using an intuitive DSL:
+
+```php
+$things = [
+	['name' => 'Mark', 'age' => 15],
+	['name' => 'Susan', 'age' => 30]
+	['name' => 'Lucy', 'age' => 25]
+];
+
+$bigPeople = Hash::extract('{n}[age>21].name', $things);
+
+// $bigPeople will contain ['Susan', 'Lucy']
+```
+
+Check the [official Hash class documentation](http://book.cakephp.org/3.0/en/core-utility-libraries/hash.html)
+
+### Inflector
+
+The Inflector class takes a string and can manipulate it to handle word variations
+such as pluralizations or camelizing.
+
+```php
+echo Inflector::pluralize('Apple'); // echoes Apples
+
+echo Inflector::singularize('People'); // echoes Person
+```
+
+Check the [official Inflector class documentation](http://book.cakephp.org/3.0/en/core-utility-libraries/inflector.html)
+
+### String
+
+The String class includes convenience methods for creating and manipulating strings.
+
+```php
+String::insert(
+    'My name is :name and I am :age years old.',
+    array('name' => 'Bob', 'age' => '65')
+);
+// Returns: "My name is Bob and I am 65 years old."
+
+$text = 'This is the song that never ends.';
+$result = String::wrap($text, 22);
+
+// Returns
+This is the song
+that never ends.
+```
+
+Check the [official String class documentation](http://book.cakephp.org/3.0/en/core-utility-libraries/string.html)
+
+### Security
+
+The security library handles basic security measures such as providing methods for hashing and encrypting data.
+
+```php
+$key = 'wt1U5MACWJFTXGenFoZoiLwQGrLgdbHA';
+$result = Security::encrypt($value, $key);
+
+Security::decrypt($result, $key);
+```
+
+Check the [official Security class documentation](http://book.cakephp.org/3.0/en/core-utility-libraries/security.html)
+
+### Xml
+
+The Xml class allows you to easily transform arrays into SimpleXMLElement or DOMDocument objects
+and back into arrays again
+
+```php
+$data = array(
+    'post' => array(
+        'id' => 1,
+        'title' => 'Best post',
+        'body' => ' ... '
+    )
+);
+$xml = Xml::build($data);
+```
+
+Check the [official Xml class documentation](http://book.cakephp.org/3.0/en/core-utility-libraries/xml.html)

+ 35 - 13
src/Utility/Security.php

@@ -14,8 +14,7 @@
  */
 namespace Cake\Utility;
 
-use Cake\Core\Configure;
-use Cake\Core\Exception\Exception;
+use InvalidArgumentException;
 
 /**
  * Security Library contains utility methods related to security
@@ -32,6 +31,13 @@ class Security {
 	public static $hashType = 'sha1';
 
 /**
+ * The HMAC salt to use for encryption and decryption routines
+ *
+ * @var string
+ */
+	protected static $_salt;
+
+/**
  * Generate authorization hash.
  *
  * @return string Hash
@@ -60,7 +66,7 @@ class Security {
 
 		if ($salt) {
 			if (!is_string($salt)) {
-				$salt = Configure::read('Security.salt');
+				$salt = static::$_salt;
 			}
 			$string = $salt . $string;
 		}
@@ -86,18 +92,18 @@ class Security {
  * @param string $text Encrypted string to decrypt, normal string to encrypt
  * @param string $key Key to use as the encryption key for encrypted data.
  * @param string $operation Operation to perform, encrypt or decrypt
- * @throws \Cake\Core\Exception\Exception When there are errors.
+ * @throws \InvalidArgumentException When there are errors.
  * @return string Encrypted/Decrypted string
  */
 	public static function rijndael($text, $key, $operation) {
 		if (empty($key)) {
-			throw new Exception('You cannot use an empty key for Security::rijndael()');
+			throw new InvalidArgumentException('You cannot use an empty key for Security::rijndael()');
 		}
 		if (empty($operation) || !in_array($operation, array('encrypt', 'decrypt'))) {
-			throw new Exception('You must specify the operation for Security::rijndael(), either encrypt or decrypt');
+			throw new InvalidArgumentException('You must specify the operation for Security::rijndael(), either encrypt or decrypt');
 		}
 		if (strlen($key) < 32) {
-			throw new Exception('You must use a key larger than 32 bytes for Security::rijndael()');
+			throw new InvalidArgumentException('You must use a key larger than 32 bytes for Security::rijndael()');
 		}
 		$algorithm = MCRYPT_RIJNDAEL_256;
 		$mode = MCRYPT_MODE_CBC;
@@ -125,13 +131,13 @@ class Security {
  * @param string $key The 256 bit/32 byte key to use as a cipher key.
  * @param string $hmacSalt The salt to use for the HMAC process. Leave null to use Security.salt.
  * @return string Encrypted data.
- * @throws \Cake\Core\Exception\Exception On invalid data or key.
+ * @throws \InvalidArgumentException On invalid data or key.
  */
 	public static function encrypt($plain, $key, $hmacSalt = null) {
 		self::_checkKey($key, 'encrypt()');
 
 		if ($hmacSalt === null) {
-			$hmacSalt = Configure::read('Security.salt');
+			$hmacSalt = static::$_salt;
 		}
 
 		// Generate the encryption and hmac key.
@@ -153,11 +159,13 @@ class Security {
  * @param string $key Key to check.
  * @param string $method The method the key is being checked for.
  * @return void
- * @throws \Cake\Core\Exception\Exception When key length is not 256 bit/32 bytes
+ * @throws \InvalidArgumentException When key length is not 256 bit/32 bytes
  */
 	protected static function _checkKey($key, $method) {
 		if (strlen($key) < 32) {
-			throw new Exception(sprintf('Invalid key for %s, key must be at least 256 bits (32 bytes) long.', $method));
+			throw new InvalidArgumentException(
+				sprintf('Invalid key for %s, key must be at least 256 bits (32 bytes) long.', $method)
+			);
 		}
 	}
 
@@ -173,10 +181,10 @@ class Security {
 	public static function decrypt($cipher, $key, $hmacSalt = null) {
 		self::_checkKey($key, 'decrypt()');
 		if (empty($cipher)) {
-			throw new Exception('The data to decrypt cannot be empty.');
+			throw new InvalidArgumentException('The data to decrypt cannot be empty.');
 		}
 		if ($hmacSalt === null) {
-			$hmacSalt = Configure::read('Security.salt');
+			$hmacSalt = static::$_salt;
 		}
 
 		// Generate the encryption and hmac key.
@@ -202,4 +210,18 @@ class Security {
 		return rtrim($plain, "\0");
 	}
 
+/**
+ * Gets or sets the HMAC salt to be used for encryption/decryption
+ * routines.
+ *
+ * @param string $salt The salt to use for encryption routines
+ * @return string The currently configured salt
+ */
+	public static function salt($salt = null) {
+		if ($salt === null) {
+			return static::$_salt;
+		}
+		return static::$_salt = (string)$salt;
+	}
+
 }

+ 3 - 4
src/Utility/String.php

@@ -14,7 +14,7 @@
  */
 namespace Cake\Utility;
 
-use Cake\Core\Exception\Exception;
+use InvalidArgumentException;
 
 /**
  * String handling methods.
@@ -722,7 +722,7 @@ class String {
  * @param string $size Size in human readable string like '5MB', '5M', '500B', '50kb' etc.
  * @param mixed $default Value to be returned when invalid size was used, for example 'Unknown type'
  * @return mixed Number of bytes as integer on success, `$default` on failure if not false
- * @throws \Cake\Core\Exception\Exception On invalid Unit type.
+ * @throws \InvalidArgumentException On invalid Unit type.
  * @link http://book.cakephp.org/3.0/en/core-libraries/helpers/text.html
  */
 	public static function parseFileSize($size, $default = false) {
@@ -750,8 +750,7 @@ class String {
 		if ($default !== false) {
 			return $default;
 		}
-		throw new Exception('No unit type.');
+		throw new InvalidArgumentException('No unit type.');
 	}
 
-
 }

+ 1 - 2
src/Utility/Xml.php

@@ -14,7 +14,6 @@
  */
 namespace Cake\Utility;
 
-use Cake\Core\Configure;
 use Cake\Utility\Exception\XmlException;
 use \DOMDocument;
 
@@ -197,7 +196,7 @@ class Xml {
 		$defaults = array(
 			'format' => 'tags',
 			'version' => '1.0',
-			'encoding' => Configure::read('App.encoding'),
+			'encoding' => mb_internal_encoding(),
 			'return' => 'simplexml',
 			'pretty' => false
 		);

+ 17 - 0
src/Utility/composer.json

@@ -0,0 +1,17 @@
+{
+	"name": "cakephp/utility",
+	"description": "CakePHP Utility classes such as Inflector, String, Hash, and Security",
+	"license": "MIT",
+	"authors": [
+		{
+		"name": "CakePHP Community",
+		"homepage": "http://cakephp.org"
+	}
+	],
+	"autoload": {
+		"psr-4": {
+			"Cake\\Utility\\": "."
+		}
+	},
+	"minimum-stability": "beta"
+}

+ 15 - 6
tests/TestCase/Utility/SecurityTest.php

@@ -14,7 +14,6 @@
  */
 namespace Cake\Test\TestCase\Utility;
 
-use Cake\Core\Configure;
 use Cake\TestSuite\TestCase;
 use Cake\Utility\Security;
 
@@ -103,7 +102,7 @@ class SecurityTest extends TestCase {
 /**
  * testRijndaelInvalidOperation method
  *
- * @expectedException \Cake\Core\Exception\Exception
+ * @expectedException InvalidArgumentException
  * @return void
  */
 	public function testRijndaelInvalidOperation() {
@@ -115,7 +114,7 @@ class SecurityTest extends TestCase {
 /**
  * testRijndaelInvalidKey method
  *
- * @expectedException \Cake\Core\Exception\Exception
+ * @expectedException InvalidArgumentException
  * @return void
  */
 	public function testRijndaelInvalidKey() {
@@ -186,7 +185,7 @@ class SecurityTest extends TestCase {
 /**
  * Test that short keys cause errors
  *
- * @expectedException \Cake\Core\Exception\Exception
+ * @expectedException InvalidArgumentException
  * @expectedExceptionMessage Invalid key for encrypt(), key must be at least 256 bits (32 bytes) long.
  * @return void
  */
@@ -223,7 +222,7 @@ class SecurityTest extends TestCase {
 /**
  * Test that short keys cause errors
  *
- * @expectedException \Cake\Core\Exception\Exception
+ * @expectedException InvalidArgumentException
  * @expectedExceptionMessage Invalid key for decrypt(), key must be at least 256 bits (32 bytes) long.
  * @return void
  */
@@ -236,7 +235,7 @@ class SecurityTest extends TestCase {
 /**
  * Test that empty data cause errors
  *
- * @expectedException \Cake\Core\Exception\Exception
+ * @expectedException InvalidArgumentException
  * @expectedExceptionMessage The data to decrypt cannot be empty.
  * @return void
  */
@@ -246,4 +245,14 @@ class SecurityTest extends TestCase {
 		Security::decrypt($txt, $key);
 	}
 
+/**
+ * Tests that the salt can be set and retrieved
+ *
+ * @return void
+ */
+	public function testSalt() {
+		Security::salt('foobarbaz');
+		$this->assertEquals('foobarbaz', Security::salt());
+	}
+
 }

+ 1 - 1
tests/TestCase/Utility/StringTest.php

@@ -1427,7 +1427,7 @@ podeís adquirirla.</span></p>
 /**
  * testFromReadableSize
  *
- * @expectedException \Cake\Core\Exception\Exception
+ * @expectedException InvalidArgumentException
  * @return void
  */
 	public function testparseFileSizeException() {