Ejemplo n.º 1
0
 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);
 }
Ejemplo n.º 2
0
 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'));
 }
Ejemplo n.º 3
0
 /**
  * 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);
         }
     });
 }
Ejemplo n.º 4
0
 /**
  * @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);
         });
     }
 }
Ejemplo n.º 5
0
 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);
     });
 }
Ejemplo n.º 6
0
 /**
  * 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);
     });
 }