├── LICENSE ├── README.md ├── composer.json └── src ├── Attributes.php ├── Sanitize.php ├── SanitizeException.php └── rules ├── Abs.php ├── BasicTags.php ├── BooleanRule.php ├── Call.php ├── Decode.php ├── DefaultRule.php ├── Email.php ├── Encode.php ├── FloatRule.php ├── IntRule.php ├── Ip.php ├── LowerFirst.php ├── Lowercase.php ├── LtrimWords.php ├── Negative.php ├── NoiseWords.php ├── Numbers.php ├── Positive.php ├── RemoveScript.php ├── RemoveTags.php ├── ReplaceRandChars.php ├── Round.php ├── RtrimWords.php ├── Rule.php ├── Slug.php ├── SpecialChars.php ├── StringRule.php ├── ToType.php ├── Trim.php ├── Truncate.php ├── TruncateWords.php ├── Unserialize.php ├── UpperFirst.php └── Uppercase.php /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 RomeOz 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Sanitizator for PHP 2 | ======================= 3 | 4 | [](https://packagist.org/packages/romeOz/rock-sanitize) 5 | [](https://packagist.org/packages/romeOz/rock-sanitize) 6 | [](https://travis-ci.org/romeOz/rock-sanitize) 7 | [](http://hhvm.h4cc.de/package/romeoz/rock-sanitize) 8 | [](https://coveralls.io/r/romeOz/rock-sanitize?branch=master) 9 | [](https://packagist.org/packages/romeOz/rock-sanitize) 10 | 11 | Features 12 | ------------------- 13 | 14 | * Sanitization of scalar variable, array and object 15 | * Custom rules 16 | * Standalone module/component for [Rock Framework](https://github.com/romeOz/rock) 17 | 18 | Installation 19 | ------------------- 20 | 21 | From the Command Line: 22 | 23 | ``` 24 | composer require romeoz/rock-sanitize 25 | ``` 26 | 27 | In your composer.json: 28 | 29 | ```json 30 | { 31 | "require": { 32 | "romeoz/rock-sanitize": "*" 33 | } 34 | } 35 | ``` 36 | 37 | Quick Start 38 | ------------------- 39 | 40 | ```php 41 | use rock\sanitize\Sanitize; 42 | 43 | Sanitize::removeTags() 44 | ->lowercase() 45 | ->sanitize('Hello World!'); 46 | // output: hello world! 47 | ``` 48 | 49 | ####As Array or Object 50 | 51 | ```php 52 | use rock\sanitize\Sanitize; 53 | 54 | $input = [ 55 | 'name' => 'Tom', 56 | 'age' => -22 57 | ]; 58 | 59 | $attributes = [ 60 | 'name' => Sanitize::removeTags(), 61 | 'age' => Sanitize::abs() 62 | ]; 63 | 64 | Sanitize::attributes($attributes)->sanitize($input); 65 | /* 66 | output: 67 | 68 | [ 69 | 'name' => 'Tom', 70 | 'age' => 22 71 | ] 72 | */ 73 | 74 | // all attributes: 75 | Sanitize::attributes(Sanitize::removeTags())->sanitize($input); 76 | ``` 77 | 78 | Documentation 79 | ------------------- 80 | 81 | * [Rules](https://github.com/romeOz/rock-sanitize/blob/master/docs/rules.md) 82 | * [Custom rules](https://github.com/romeOz/rock-sanitize/blob/master/docs/custom-rules.md) 83 | 84 | [Demo](https://github.com/romeOz/docker-rock-sanitize) 85 | ------------------- 86 | 87 | * [Install Docker](https://docs.docker.com/installation/) or [askubuntu](http://askubuntu.com/a/473720) 88 | * `docker run --name demo -d -p 8080:80 romeoz/docker-rock-sanitize` 89 | * Open demo [http://localhost:8080/](http://localhost:8080/) 90 | 91 | Requirements 92 | ------------------- 93 | 94 | * PHP 5.4+ 95 | 96 | License 97 | ------------------- 98 | 99 | The Rock Sanitize is open-sourced software licensed under the [MIT license](http://opensource.org/licenses/MIT). -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "romeoz/rock-sanitize", 3 | "description": "Flexible sanitizator for PHP.", 4 | "keywords": ["sanitize", "sanitization", "sanitizator"], 5 | "type": "library", 6 | "license": "MIT", 7 | "support": { 8 | "email": "serggalka@gmail.com", 9 | "issues": "https://github.com/romeOz/rock-sanitize/issues", 10 | "source": "https://github.com/romeOz/rock-sanitize" 11 | }, 12 | "authors": [ 13 | { 14 | "name": "Ruslan", 15 | "email": "serggalka@gmail.com" 16 | } 17 | ], 18 | "require": { 19 | "php": ">=5.4.0", 20 | "romeoz/rock-base" : "*@dev" 21 | }, 22 | "require-dev": { 23 | "phpunit/phpunit": "^4.7.0" 24 | }, 25 | "autoload": { 26 | "psr-4": { 27 | "rock\\sanitize\\": "src/" 28 | } 29 | }, 30 | "extra": { 31 | "branch-alias": { 32 | "dev-master": "0.11-dev" 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /src/Attributes.php: -------------------------------------------------------------------------------- 1 | attributes; 22 | if (is_object($input)) { 23 | $object = $input; 24 | $input = (array)$input; 25 | } 26 | if ($attributes instanceof Sanitize) { 27 | $attributes = $this->each($attributes, $input); 28 | } 29 | $result = []; 30 | foreach ($attributes as $attribute => $sanitize) { 31 | if (!$sanitize instanceof Sanitize) { 32 | throw new SanitizeException("`{$attribute}` is not `" . Sanitize::className() . "`"); 33 | } 34 | if ($attribute === $this->remainder) { 35 | $result = array_merge($result, $this->remainder($sanitize, $attributes, $input)); 36 | continue; 37 | } 38 | 39 | if (strrpos($attribute, '.') !== false && ArrayHelper::getValue($input, explode('.', $attribute))) { 40 | $input = $this->chain($sanitize, $input, $attribute); 41 | continue; 42 | } 43 | 44 | if (!isset($input[$attribute])) { 45 | continue; 46 | } 47 | 48 | if ((is_array($input[$attribute]) || is_object($input[$attribute]))) { 49 | if (!$this->recursive) { 50 | continue; 51 | } 52 | $this->attributes = is_array($this->attributes) && isset($this->attributes[$attribute]) 53 | ? $this->attributes[$attribute] 54 | : $this->attributes; 55 | $result[$attribute] = $this->sanitize($input[$attribute]); 56 | continue; 57 | } 58 | $result[$attribute] = $sanitize->sanitize($input[$attribute]); 59 | } 60 | 61 | $result = is_int(key($result)) ? $result + $input : array_merge($input, $result); 62 | if (isset($object)) { 63 | foreach ($result as $property => $value) { 64 | $object->$property = $value; 65 | } 66 | return $object; 67 | } 68 | return $result; 69 | } 70 | 71 | protected function each(Sanitize $sanitize, $input) 72 | { 73 | $attributes = []; 74 | foreach ($input as $key => $value) { 75 | $attributes[$key] = $sanitize; 76 | } 77 | return $attributes; 78 | } 79 | 80 | protected function remainder(Sanitize $sanitize, array $attributes, $input) 81 | { 82 | $input = ArrayHelper::diffByKeys($input, array_keys($attributes)); 83 | $this->attributes = $sanitize; 84 | return $this->sanitize($input); 85 | } 86 | 87 | protected function chain(Sanitize $sanitize, $input, $attribute) 88 | { 89 | $callback = function ($value) use ($sanitize, $attribute) { 90 | if (is_array($value)) { 91 | if (!$this->recursive) { 92 | return $value; 93 | } 94 | $this->attributes = is_array($this->attributes) && isset($this->attributes[$attribute]) 95 | ? $this->attributes[$attribute] 96 | : $this->attributes; 97 | return $this->sanitize($value); 98 | } 99 | return $sanitize->sanitize($value); 100 | }; 101 | return ArrayHelper::updateValue($input, explode('.', $attribute), $callback); 102 | } 103 | } -------------------------------------------------------------------------------- /src/Sanitize.php: -------------------------------------------------------------------------------- 1 | rules = array_merge($this->defaultRules(), $this->rules); 117 | } 118 | 119 | /** 120 | * Sets a list rules. 121 | * @param array $rules 122 | * @return $this 123 | */ 124 | public function setRules(array $rules) 125 | { 126 | $this->rules = array_merge($this->rules, $rules); 127 | return $this; 128 | } 129 | 130 | /** 131 | * Enable recursive mode. 132 | * @param bool $enable 133 | * @return $this 134 | */ 135 | public function setRecursive($enable) 136 | { 137 | $this->recursive = $enable; 138 | return $this; 139 | } 140 | 141 | /** 142 | * Sets a label remainder. 143 | * @param string $label 144 | * @return $this 145 | */ 146 | public function setRemainder($label) 147 | { 148 | $this->remainder = $label; 149 | return $this; 150 | } 151 | 152 | /** 153 | * Sanitize value. 154 | * 155 | * @param mixed $input 156 | * @return mixed 157 | * @throws SanitizeException 158 | */ 159 | public function sanitize($input) 160 | { 161 | foreach ($this->rawRules as $rule) { 162 | if ($rule instanceof Attributes) { 163 | $config = [ 164 | 'remainder' => $this->remainder, 165 | 'recursive' => $this->recursive 166 | ]; 167 | Instance::configure($rule, $config); 168 | return $rule->sanitize($input); 169 | } 170 | $input = $rule->sanitize($input); 171 | 172 | if ($rule->recursive && (is_array($input) || is_object($input))) { 173 | $config['attributes'] = $this; 174 | return (new Attributes($config))->sanitize($input); 175 | } 176 | } 177 | 178 | return $input; 179 | } 180 | 181 | /** 182 | * Exists rule. 183 | * @param string $name name of rule. 184 | * @return bool 185 | */ 186 | public function existsRule($name) 187 | { 188 | return isset($this->rules[$name]); 189 | } 190 | 191 | /** 192 | * @return rules\Rule[] 193 | */ 194 | public function getRawRules() 195 | { 196 | return $this->rawRules; 197 | } 198 | 199 | public function __call($name, $arguments) 200 | { 201 | if (method_exists($this, "{$name}Internal")) { 202 | return call_user_func_array([$this, "{$name}Internal"], $arguments); 203 | } 204 | 205 | if (!isset($this->rules[$name])) { 206 | throw new SanitizeException("Unknown rule: {$name}"); 207 | } 208 | if (!class_exists($this->rules[$name])) { 209 | throw new SanitizeException(SanitizeException::UNKNOWN_CLASS, ['class' => $this->rules[$name]]); 210 | } 211 | $rule = $this->getInstanceRule($name, $arguments); 212 | $this->rawRules[] = $rule; 213 | return $this; 214 | } 215 | 216 | public static function __callStatic($name, $arguments) 217 | { 218 | return call_user_func_array([static::getInstance(), $name], $arguments); 219 | } 220 | 221 | protected function attributesInternal($attributes) 222 | { 223 | $this->rawRules = []; 224 | $this->rawRules[] = new Attributes(['attributes' => $attributes, 'remainder' => $this->remainder]); 225 | 226 | return $this; 227 | } 228 | 229 | protected function recursiveInternal($enable = true) 230 | { 231 | $this->recursive = $enable; 232 | return $this; 233 | } 234 | 235 | protected function rulesInternal(array $rules) 236 | { 237 | foreach ($rules as $rule => $args) { 238 | if (is_int($rule)) { 239 | $rule = $args; 240 | $args = []; 241 | } 242 | if (is_array($rule)) { 243 | $args = (array)current($rule); 244 | $rule = key($rule); 245 | } 246 | call_user_func_array([$this, $rule], $args); 247 | } 248 | return $this; 249 | } 250 | 251 | /** 252 | * Returns instance rule. 253 | * @param string $name name of rule 254 | * @param array $arguments 255 | * @return Rule 256 | */ 257 | protected function getInstanceRule($name, array $arguments) 258 | { 259 | $reflect = new \ReflectionClass($this->rules[$name]); 260 | return $reflect->newInstanceArgs($arguments); 261 | } 262 | 263 | /** 264 | * Returns instance. 265 | * 266 | * If exists {@see \rock\di\Container} that uses it. 267 | * @return static 268 | */ 269 | protected static function getInstance() 270 | { 271 | if (class_exists('\rock\di\Container')) { 272 | return \rock\di\Container::load(static::className()); 273 | } 274 | return new static(); 275 | } 276 | 277 | protected function defaultRules() 278 | { 279 | return [ 280 | 'abs' => Abs::className(), 281 | 'basicTags' => BasicTags::className(), 282 | 'bool' => BooleanRule::className(), 283 | 'ip' => Ip::className(), 284 | 'call' => Call::className(), 285 | 'decode' => Decode::className(), 286 | 'defaultValue' => DefaultRule::className(), 287 | 'email' => Email::className(), 288 | 'encode' => Encode::className(), 289 | 'float' => FloatRule::className(), 290 | 'int' => IntRule::className(), 291 | 'lowercase' => Lowercase::className(), 292 | 'lowerFirst' => LowerFirst::className(), 293 | 'ltrimWords' => LtrimWords::className(), 294 | 'negative' => Negative::className(), 295 | 'noiseWords' => NoiseWords::className(), 296 | 'numbers' => Numbers::className(), 297 | 'positive' => Positive::className(), 298 | 'specialChars' => SpecialChars::className(), 299 | 'removeScript' => RemoveScript::className(), 300 | 'removeTags' => RemoveTags::className(), 301 | 'replaceRandChars' => ReplaceRandChars::className(), 302 | 'round' => Round::className(), 303 | 'rtrimWords' => RtrimWords::className(), 304 | 'string' => StringRule::className(), 305 | 'toType' => ToType::className(), 306 | 'slug' => Slug::className(), 307 | 'trim' => Trim::className(), 308 | 'truncate' => Truncate::className(), 309 | 'truncateWords' => TruncateWords::className(), 310 | 'unserialize' => Unserialize::className(), 311 | 'uppercase' => Uppercase::className(), 312 | 'upperFirst' => UpperFirst::className(), 313 | ]; 314 | } 315 | } -------------------------------------------------------------------------------- /src/SanitizeException.php: -------------------------------------------------------------------------------- 1 |