cool false, // fake data after a find call (defaults to false) 'fields' => [], // additional fields or custom mapping to a specific snippet type (defaults to XSS) 'skipFields' => ['id', 'slug'] // fields of the schema that should be skipped ]; protected $_snippets = []; /** * HazardableBehavior::setup() * * @param Model $Model * @param array $config * @return void */ public function setup(Model $Model, $config = []) { $this->settings[$Model->alias] = $config + $this->_defaultConfig; } /** * BeforeSave() to inject the hazardous strings into the model data for save(). * * Note: Remember to disable validation as you want to insert those strings just for * testing purposes. */ public function beforeSave(Model $Model, $options = []) { $fields = $this->_fields($Model); foreach ($fields as $field) { $length = 0; $schema = $Model->schema($field); if (!empty($schema['length'])) { $length = $schema['length']; } $Model->data[$Model->alias][$field] = $this->_snippet($length); } return true; } /** * AfterFind() to inject the hazardous strings into the retrieved model data. * Only activate this if you have not persistently stored any hazardous strings yet. */ public function afterFind(Model $Model, $results, $primary = false) { if (empty($this->settings[$Model->alias]['replaceFind'])) { return $results; } foreach ($results as $key => $result) { foreach ($result as $model => $row) { $fields = $this->_fields($Model); foreach ($fields as $field) { $length = 0; $schema = $Model->schema($field); if (!empty($schema['length'])) { $length = $schema['length']; } $results[$key][$model][$field] = $this->_snippet($length); } } } return $results; } /** * @param int $maxLength The lenght of the field if applicable to return a suitable snippet * @return string Hazardous string */ protected function _snippet($maxLength = 0) { $snippets = $this->_snippets(); $max = count($snippets) - 1; if ($maxLength) { foreach ($snippets as $key => $snippet) { if (mb_strlen($snippet) > $maxLength) { break; } $max = $key; } } $keyByChance = mt_rand(0, $max); return $snippets[$keyByChance]; } /** * @return array */ protected function _snippets() { if ($this->_snippets) { return $this->_snippets; } $snippetArray = HazardLib::xssStrings(); $snippetArray[] = ''; $snippetArray[] = '<'; usort($snippetArray, [$this, '_sort']); $this->_snippets = $snippetArray; return $snippetArray; } /** * Sort all snippets by length (ASC) */ protected function _sort($a, $b) { return strlen($a) - strlen($b); } /** * @return array */ protected function _fields(Model $Model) { $fields = []; $schema = $Model->schema(); foreach ($schema as $key => $field) { if (!in_array($field['type'], ['text', 'string'])) { continue; } if ($this->settings[$Model->alias]['skipFields'] && in_array($key, $this->settings[$Model->alias]['skipFields'])) { continue; } $fields[] = $key; } return $fields; } }