public function testConfigSet() { $behavior = new Behavior(['model' => 'li3_behaviors\\tests\\mocks\\data\\model\\MockPost', 'test' => 'case']); $behavior->config('test', 'phase'); $expected = 'phase'; $result = $behavior->config('test'); $this->assertEqual($expected, $result); }
public function testConfig() { $behavior = new Behavior(['test1' => 'value1']); $this->assertEqual('value1', $behavior->config('test1')); $behavior->config(['test2' => 'value2']); $this->assertEqual('value1', $behavior->config('test1')); $this->assertEqual('value2', $behavior->config('test2')); $behavior->config(['test1' => 'value1 changed', 'test2' => 'value2']); $this->assertEqual('value1 changed', $behavior->config('test1')); $this->assertEqual('value2', $behavior->config('test2')); }
/** * Initializer function called by the constructor unless the constructor `'init'` flag is set * to `false`. * * @see lithium\core\Object * @throws ConfigException */ public function _init() { parent::_init(); if (!($model = $this->_model)) { throw new ConfigException("`'model'` option needs to be defined."); } $behavior = $this; $model::applyFilter('save', function ($self, $params, $chain) use($behavior) { if ($behavior->invokeMethod('_beforeSave', [$params])) { return $chain->next($self, $params, $chain); } }); $model::applyFilter('delete', function ($self, $params, $chain) use($behavior) { if ($behavior->invokeMethod('_beforeDelete', [$params])) { return $chain->next($self, $params, $chain); } }); }
/** * @todo We may also need to filter `remove()`. */ protected function _init() { parent::_init(); if (PHP_SAPI === 'cli') { return true; } if ($model = $this->_model) { $behavior = $this; $model::applyFilter('save', function ($self, $params, $chain) use($behavior) { $options = ['placeholders' => []]; $configs = $behavior->_config; $fields = $behavior::_formattedFields($configs['fields']); $source = $destination = $configName = []; $data = $behavior::_modified($params['data'], $fields); $dataKeys = array_keys($data); if (empty($dataKeys)) { return $chain->next($self, $params, $chain); } $queried = $params['entity']->export()['data']; if (0 === count(array_intersect_key($queried, $fields))) { return $chain->next($self, $params, $chain); } $params['data'] = []; $params['entity']->set($data); $entity = $params['entity']; $entityData['model'] = $entity->model(); $entityData['data'] = $entity->data(); if (!isset($configs['placeholders'])) { $configs['placeholders'] = []; } $defaults = ['save' => null, 'remove' => null]; $skip = []; $fieldCount = 0; foreach ($fields as $field => $name) { if (array_key_exists($field, $data)) { $configName[$field] = $name; $source[$field] = $_FILES[$field]['tmp_name']; $settings = UploadableStorage::config($name); $settings += $defaults; $path = $settings['save']; $newFile = $_FILES[$field]['name']; if ($entity->exists()) { if (!$entity->modified($field)) { $skip[$field] = true; } else { // We delete the old file $oldFile = $entity->export()['data'][$field]; $removeOptions['placeholders'] = UploadableStorage::placeholders($oldFile, $configs['placeholders'] + ['field' => $field], $entityData); $removePath = UploadableStorage::interpolate($settings['remove'], $removeOptions); UploadableStorage::remove($removePath, $removeOptions + ['name' => $name]); if (null === $data[$field]) { $skip[$field] = true; continue; } $options['placeholders'] = UploadableStorage::placeholders($newFile, $configs['placeholders'] + ['field' => $field], $entityData); $destination[$field] = UploadableStorage::interpolate($path, $options); /** * The field has been modified to now contain 'null' so we * remove the field from the config so that, later on, we don't * try to upload a non-existent file later. */ if (null === $entity->{$field}) { $params['entity']->{$field} = null; unset($configs['fields'][$field]); } else { /** * the field has been modified but it contains a value * so we must upload the new one. */ $fieldValue = static::fieldValue($path, $options['placeholders']); $params['entity']->{$field} = $fieldValue; } } } else { $options['placeholders'] = UploadableStorage::placeholders($newFile, $configs['placeholders'] + ['field' => $field], $entityData); $fieldValue = static::fieldValue($path, $options['placeholders']); $destination[$field] = UploadableStorage::interpolate($path, $options); $params['entity']->{$field} = $fieldValue; } } else { $fieldCount++; } } if (!$params['entity']->validates()) { return false; } $saved = $chain->next($self, $params, $chain); if ($fieldCount == count($fields)) { return $saved; } $options['placeholders'] += $params['entity']->data(); $uploaded = []; foreach ($fields as $field => $name) { if (!isset($skip[$field]) || $skip[$field] !== true) { $options['name'] = $configName[$field]; $uploaded[] = UploadableStorage::save($source[$field], $destination[$field], $options); } } return $saved && !in_array(false, $uploaded, true); }); $model::applyFilter('find', function ($self, $params, $chain) use($behavior) { $data = $chain->next($self, $params, $chain); switch ($params['type']) { case 'first': $entity = $behavior->invokeMethod('_assignAccessors', [$data]); return $entity; break; case 'all': foreach ($data as $datum) { $entity = $behavior->invokeMethod('_assignAccessors', [$datum]); } return $data; break; default: return $data; break; } }); $model::applyFilter('delete', function ($self, $params, $chain) use($behavior) { $entity = $params['entity']; $entityData['model'] = $entity->model(); $entityData['data'] = $entity->data(); $configs = $behavior->_config; $fields = $behavior::_formattedFields($configs['fields']); if (!isset($configs['placeholders'])) { $configs['placeholders'] = []; } $results = []; foreach ($fields as $field => $name) { $path = UploadableStorage::config($name)['remove']; $existingFile = $entity->export()['data'][$field]; $options['placeholders'] = UploadableStorage::placeholders($existingFile, $configs['placeholders'] + ['field' => $field], $entityData); $destination = UploadableStorage::interpolate($path, $options); $results[] = UploadableStorage::remove($destination, $options + ['name' => $name]); } $deleted = $chain->next($self, $params, $chain); return $deleted && !in_array(false, $results, true); }); } }
protected static function _validates($model, Behavior $behavior) { $model::applyFilter('validates', function ($self, $params, $chain) use($behavior) { $entity =& $params['entity']; if (!$entity->i18n) { // When no i18n is present, we don't have to do anything. return $chain->next($self, $params, $chain); } $config = $behavior->config(); $entity = static::_syncFromI18n($entity, $config); if ($diff = array_diff(array_keys($entity->i18n), $config['fields'])) { "Unknown translated field/s `" . implode(', ', $diff); "`."; throw new Exception($message); } // Validate original fields, as well as any translation // that are present. By default translation are sparse // and cannot be *required*. $rules =& $params['options']['rules']; foreach ($config['fields'] as $field) { if (!isset($rules[$field])) { continue; } foreach ($config['locales'] as $locale) { if ($locale === $config['locale']) { continue; } $inline = static::_composeField($field, $locale, '.'); if (isset($rules[$inline])) { continue; } $rules[$inline] = $rules[$field]; } } foreach ($rules as $field => $rule) { if (strpos($field, 'i18n') === false) { continue; } foreach ($rule as &$r) { $r['required'] = false; } } return $chain->next($self, $params, $chain); }); }
/** * Adds the `tag` finder. Implements custom logic for SQL * based data sources otherwise a pass through. * * @deprecated * @param string $model Class name of the model. * @param object $behavior Instance of the behavior. * @return void */ protected static function _finders($model, Behavior $behavior) { $connection = get_class($model::connection()); $model::finder('tag', function ($self, $params, $chain) use($behavior, $connection) { trigger_error('The `tag` finder is deprecated, use regular finders instead.', E_USER_DEPRECATED); $field = $behavior->config('field'); if (!$connection::enabled('arrays')) { $params['options']['conditions'][$field] = ['REGEXP' => '(,|^)' . $params['options']['conditions'][$field] . '(,|$)']; } return $chain->next($self, $params, $chain); }); }