Skip to content

Commit

Permalink
Merge pull request #399 from josegonzalez/field-value-replacement
Browse files Browse the repository at this point in the history
Add support for field-value replacements
  • Loading branch information
josegonzalez committed Jul 23, 2016
2 parents 389a36e + 72cb7af commit aee88b0
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 5 deletions.
15 changes: 12 additions & 3 deletions docs/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,19 @@ passed in under each field in your behavior configuration.
- {DS}: Replaced by a ``DIRECTORY_SEPARATOR``
- {model}: Replaced by the Table-alias() method.
- {table}: Replaced by the Table->table() method.
- {field}: Replaced by the field name.
- {field}: Replaced by the name of the field which will store
the upload filename.
- {field-value:(\w+)}: Replaced by value contained in the
current entity in the specified field. As an example, if
your path has ``{field-value:unique_id}`` and the entity
being saved has a value of ``4b3403665fea6`` for the field
``unique_id``, then ``{field-value:unique_id}`` will be
replaced with ``4b3403665fea6``. This replacement can be used
multiple times for one or more fields. If the value is not
a string or zero-length, a LogicException will be thrown.
- {primaryKey}: Replaced by the entity primary key, when
available. If used on a new record being created, will have
undefined behavior.
available. If used on a new record being created, a
LogicException will be thrown.
- {year}: Replaced by ``date('Y')``
- {month}: Replaced by ``date('m')``
- {day}: Replaced by ``date('d')``
Expand Down
15 changes: 15 additions & 0 deletions src/File/Path/Basepath/DefaultTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,21 @@ public function basepath()
'{DS}' => DIRECTORY_SEPARATOR,
];

if (preg_match_all("/{field-value:(\w+)}/", $path, $matches)) {
foreach ($matches[1] as $field) {
$value = $this->entity->get($field);
if ($value === null) {
throw new LogicException(sprintf('Field value for substitution is missing: %s', $field));
}if (!is_scalar($value)) {
throw new LogicException(sprintf('Field value for substitution must be a integer, float, string or boolean: %s', $field));
} elseif (strlen($value) < 1) {
throw new LogicException(sprintf('Field value for substitution must be non-zero in length: %s', $field));
}

$replacements[sprintf('{field-value:%s}', $field)] = $value;
}
}

return str_replace(
array_keys($replacements),
array_values($replacements),
Expand Down
59 changes: 57 additions & 2 deletions tests/TestCase/File/Path/Basepath/DefaultTraitTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public function testNewEntity()
$mock->data = ['name' => 'filename'];
$mock->field = 'field';
$mock->entity->expects($this->once())->method('isNew')->will($this->returnValue(true));
$this->assertEquals('webroot/files/Table-field/1/', $mock->basepath());
$mock->basepath();
}

public function testExitingEntityWithCompositePrimaryKey()
Expand All @@ -76,7 +76,7 @@ public function testExitingEntityWithCompositePrimaryKey()
$mock->field = 'field';
$mock->entity->expects($this->once())->method('isNew')->will($this->returnValue(false));
$mock->table->expects($this->once())->method('primaryKey')->will($this->returnValue(['id', 'other_id']));
$this->assertEquals('webroot/files/Table-field/1/', $mock->basepath());
$mock->basepath();
}

public function testYearWithMonthPath()
Expand Down Expand Up @@ -118,4 +118,59 @@ public function testModelFieldYearWithMonthAndDayPath()

$this->assertEquals('webroot/files/Table/field/' . date("Y") . '/' . date("m") . '/' . date("d") . '/', $mock->basepath());
}

public function testFieldValueMissing()
{
$this->setExpectedException('LogicException', 'Field value for substitution is missing: field');

$mock = $this->getMockForTrait('Josegonzalez\Upload\File\Path\Basepath\DefaultTrait');
$mock->entity = $this->getMock('Cake\ORM\Entity');
$mock->table = $this->getMock('Cake\ORM\Table');
$mock->settings = ['path' => 'webroot{DS}files{DS}{model}{DS}{field-value:field}{DS}'];
$mock->data = ['name' => 'filename'];
$mock->field = 'field';
$mock->entity->expects($this->any())->method('get')->will($this->returnValue(null));
$mock->basepath();
}

public function testFieldValueNonScalar()
{
$this->setExpectedException('LogicException', 'Field value for substitution must be a integer, float, string or boolean: field');

$mock = $this->getMockForTrait('Josegonzalez\Upload\File\Path\Basepath\DefaultTrait');
$mock->entity = $this->getMock('Cake\ORM\Entity');
$mock->table = $this->getMock('Cake\ORM\Table');
$mock->settings = ['path' => 'webroot{DS}files{DS}{model}{DS}{field-value:field}{DS}'];
$mock->data = ['name' => 'filename'];
$mock->field = 'field';
$mock->entity->expects($this->any())->method('get')->will($this->returnValue([]));
$mock->basepath();
}

public function testFieldValueZeroLength()
{
$this->setExpectedException('LogicException', 'Field value for substitution must be non-zero in length: field');

$mock = $this->getMockForTrait('Josegonzalez\Upload\File\Path\Basepath\DefaultTrait');
$mock->entity = $this->getMock('Cake\ORM\Entity');
$mock->table = $this->getMock('Cake\ORM\Table');
$mock->settings = ['path' => 'webroot{DS}files{DS}{model}{DS}{field-value:field}{DS}'];
$mock->data = ['name' => 'filename'];
$mock->field = 'field';
$mock->entity->expects($this->any())->method('get')->will($this->returnValue(''));
$mock->basepath();
}

public function testFieldValue()
{
$mock = $this->getMockForTrait('Josegonzalez\Upload\File\Path\Basepath\DefaultTrait');
$mock->entity = $this->getMock('Cake\ORM\Entity');
$mock->table = $this->getMock('Cake\ORM\Table');
$mock->settings = ['path' => 'webroot{DS}files{DS}{model}{DS}{field-value:field}{DS}'];
$mock->data = ['name' => 'filename'];
$mock->field = 'field';
$mock->entity->expects($this->any())->method('get')->will($this->returnValue('value'));
$mock->table->expects($this->once())->method('alias')->will($this->returnValue('Table'));
$this->assertEquals('webroot/files/Table/value/', $mock->basepath());
}
}

0 comments on commit aee88b0

Please sign in to comment.