588 lines
14 KiB
PHP
588 lines
14 KiB
PHP
<?php
|
|
|
|
namespace Trinity\Component\Propel;
|
|
|
|
use Symfony\Component\Intl\Exception\InvalidArgumentException;
|
|
use Trinity\Component\Utils\Propel as PropelUtils;
|
|
|
|
class UploadableBehavior extends \Behavior
|
|
{
|
|
protected $fields = array();
|
|
protected $dirs = array();
|
|
protected $i18n_upload_fields = array();
|
|
protected $i18n_upload_paths = array();
|
|
|
|
protected $tableModificationOrder = 90;
|
|
|
|
protected function getColumnGetter($columnName)
|
|
{
|
|
if ($this->getTable()->getColumn($columnName)) {
|
|
return 'get'.$this->getTable()->getColumn($columnName)->getPhpName();
|
|
}
|
|
|
|
return PropelUtils::getGetter($columnName);
|
|
}
|
|
|
|
protected function getColumnSetter($columnName)
|
|
{
|
|
if ($this->getTable()->getColumn($columnName)) {
|
|
return 'set'.$this->getTable()->getColumn($columnName)->getPhpName();
|
|
}
|
|
|
|
return PropelUtils::getSetter($columnName);
|
|
}
|
|
|
|
protected function generateConfiguration()
|
|
{
|
|
$this->fields = array_map('trim', explode(',', $this->getParameter('fields')));
|
|
$path = array_map('trim', explode(',', $this->getParameter('paths')));
|
|
|
|
if (count($this->fields) != count($path)) {
|
|
throw new InvalidArgumentException(sprintf(
|
|
'You must give a path for each field specified in \'fields\' parameter. %s field for %s path',
|
|
count($this->fields),
|
|
count($path)
|
|
));
|
|
}
|
|
|
|
foreach ($this->fields as $k => $v) {
|
|
$this->dirs[$v] = $path[$k];
|
|
}
|
|
}
|
|
|
|
protected function getFields()
|
|
{
|
|
return $this->fields;
|
|
}
|
|
|
|
protected function getDirs()
|
|
{
|
|
return $this->dirs;
|
|
}
|
|
|
|
protected function getDir($field)
|
|
{
|
|
return isset($this->dirs[$field]) ? $this->dirs[$field] : null;
|
|
}
|
|
|
|
public function modifyTable()
|
|
{
|
|
$this->generateConfiguration();
|
|
|
|
$table = $this->getTable();
|
|
|
|
$i18n = $table->hasBehavior('i18n');
|
|
if ($i18n) {
|
|
$i18n_behavior = $i18n ? $table->getBehavior('i18n') : null;
|
|
$i18n_fields = $i18n_behavior ? array_map('trim',explode(',', $i18n_behavior->getParameter('i18n_columns'))) : array();
|
|
$i18n_table_name = $i18n_behavior->replaceTokens($i18n_behavior->getParameter('i18n_table'));
|
|
$i18n_table = $table->getDatabase()->getTable($i18n_table_name);
|
|
|
|
foreach ($this->getFields() as $k => $field) {
|
|
if (in_array($field, $i18n_fields)) {
|
|
$this->i18n_upload_fields[] = $field;
|
|
$this->i18n_upload_paths[$field] = $this->dirs[$field];
|
|
|
|
unset(
|
|
$this->fields[$k],
|
|
$this->dirs[$field]
|
|
);
|
|
}
|
|
}
|
|
|
|
if (!empty($this->i18n_upload_fields) && !empty($this->i18n_upload_paths)) {
|
|
$uploadableBehavior = new UploadableBehavior();
|
|
$uploadableBehavior->setName('uploadable');
|
|
$uploadableBehavior->addParameter(array(
|
|
'name' => 'fields',
|
|
'value' => implode(',', $this->i18n_upload_fields)
|
|
));
|
|
$uploadableBehavior->addParameter(array(
|
|
'name' => 'paths',
|
|
'value' => implode(',', $this->i18n_upload_paths)
|
|
));
|
|
$i18n_table->addBehavior($uploadableBehavior);
|
|
}
|
|
}
|
|
|
|
foreach ($this->getFields() as $field) {
|
|
$field = trim($field);
|
|
if (!$table->hasColumn($field)) {
|
|
$table->addColumn(array(
|
|
'name' => $field,
|
|
'type' => 'VARCHAR',
|
|
'size' => '255',
|
|
));
|
|
}
|
|
}
|
|
}
|
|
|
|
public function objectFilter(&$script)
|
|
{
|
|
$this->addSettersRollbacks($script);
|
|
}
|
|
|
|
public function objectMethods($builder)
|
|
{
|
|
$this->addAttributes($script);
|
|
$this->addGetNewFilename($script);
|
|
$this->addGetUploadDir($script);
|
|
$this->addUploadMethod($script);
|
|
$this->addSaveFileMethod($script);
|
|
$this->addRemoveMethod($script);
|
|
$this->addDeleteMethod($script);
|
|
$this->addWebPathMethod($script);
|
|
$this->addI18nWebPathMethod($script);
|
|
$this->addHasUploadedFieldMethod($script);
|
|
$this->addGetterAsFile($script);
|
|
|
|
return $script;
|
|
}
|
|
|
|
public function preSave()
|
|
{
|
|
$script = '';
|
|
foreach ($this->fields as $k => $field) {
|
|
$camel_field = PropelUtils::camelCase($field);
|
|
$script .= sprintf('$this->upload%s();%s', $camel_field, PHP_EOL);
|
|
}
|
|
|
|
return $script;
|
|
}
|
|
|
|
public function postInsert()
|
|
{
|
|
$script = '';
|
|
foreach ($this->fields as $k => $field) {
|
|
$camel_field = PropelUtils::camelCase($field);
|
|
$script .= sprintf('$this->save%sFile();%s', $camel_field, PHP_EOL);
|
|
}
|
|
|
|
return $script;
|
|
}
|
|
|
|
public function postUpdate()
|
|
{
|
|
$script = '';
|
|
foreach ($this->fields as $k => $field) {
|
|
$camel_field = PropelUtils::camelCase($field);
|
|
$script .= sprintf('$this->save%sFile();%s', $camel_field, PHP_EOL);
|
|
}
|
|
|
|
return $script;
|
|
}
|
|
|
|
public function postSave()
|
|
{
|
|
$script = '';
|
|
foreach ($this->fields as $k => $field) {
|
|
$camel_field = PropelUtils::camelCase($field);
|
|
$script .= <<<EOL
|
|
|
|
if (\$this->delete_$field) {
|
|
\$this->remove$camel_field();
|
|
}
|
|
|
|
EOL;
|
|
}
|
|
|
|
return $script;
|
|
}
|
|
|
|
public function postDelete()
|
|
{
|
|
$script = '';
|
|
foreach ($this->fields as $k => $field) {
|
|
$camel_field = PropelUtils::camelCase($field);
|
|
$script .= sprintf('$this->set%s(null);%s', $camel_field, PHP_EOL);
|
|
$script .= sprintf('$this->setDelete%s(true);%s', $camel_field, PHP_EOL);
|
|
$script .= sprintf('$this->remove%s();%s', $camel_field, PHP_EOL);
|
|
$script .= ' '.PHP_EOL;
|
|
}
|
|
|
|
return $script;
|
|
}
|
|
|
|
protected function addAttributes(&$script)
|
|
{
|
|
$dirs = var_export($this->dirs, true);
|
|
|
|
$rollbacks = '';
|
|
$delete = '';
|
|
$files = '';
|
|
$has_uploaded_file = '';
|
|
|
|
$upload = sprintf("protected \$uploadDirs = %s;%s", $dirs, PHP_EOL.PHP_EOL);
|
|
foreach ($this->getFields() as $field) {
|
|
$rollbacks.= sprintf("public \$rollback_%s = null;%s", $field, PHP_EOL.PHP_EOL);
|
|
$files.= sprintf("public \$%s_file = null;%s", $field, PHP_EOL.PHP_EOL);
|
|
$delete.= sprintf("public \$delete_%s = false;%s", $field, PHP_EOL.PHP_EOL);
|
|
$has_uploaded_file.= sprintf("public \$has_uploaded_%s = false;%s", $field, PHP_EOL.PHP_EOL);
|
|
}
|
|
if (!empty($this->dirs)) {
|
|
$script .= <<<EOS
|
|
$upload
|
|
EOS;
|
|
}
|
|
if ($rollbacks != '') {
|
|
$script .= <<<EOS
|
|
$rollbacks
|
|
EOS;
|
|
}
|
|
if ($delete != '') {
|
|
$script .= <<<EOS
|
|
$delete
|
|
EOS;
|
|
}
|
|
if ($files != '') {
|
|
$script .= <<<EOS
|
|
$files
|
|
EOS;
|
|
}
|
|
if ($has_uploaded_file != '') {
|
|
$script .= <<<EOS
|
|
$has_uploaded_file
|
|
EOS;
|
|
}
|
|
}
|
|
|
|
protected function addGetNewFilename(&$script)
|
|
{
|
|
if (empty($this->fields)) {
|
|
return;
|
|
}
|
|
|
|
$script.= <<<EOS
|
|
|
|
/**
|
|
* Return a new filename randomly
|
|
*
|
|
* @param \$extension
|
|
* @return string
|
|
*
|
|
*/
|
|
public function getNewFilename(\$extension)
|
|
{
|
|
return md5(time().uniqid()).(\$extension ? '.'.\$extension : '');
|
|
}
|
|
|
|
EOS;
|
|
}
|
|
|
|
protected function addGetUploadDir(&$script)
|
|
{
|
|
if (empty($this->dirs)) {
|
|
return;
|
|
}
|
|
|
|
$script.= <<<EOS
|
|
|
|
/**
|
|
* Return the upload dir of \$field field
|
|
*
|
|
* @param \$field
|
|
* @return mixed
|
|
*/
|
|
public function getUploadDir(\$field)
|
|
{
|
|
\$dir = \$this->uploadDirs[\$field];
|
|
|
|
\$transform_dir = preg_replace_callback(
|
|
'`\{(.*)\}`sU',
|
|
function (\$matches) {
|
|
return method_exists(\$this, \$matches[1]) ? (string) call_user_func(array(\$this, \$matches[1])) : '';
|
|
}, \$dir
|
|
);
|
|
|
|
return (is_string(\$transform_dir))?\$transform_dir:\$dir;
|
|
}
|
|
|
|
EOS;
|
|
}
|
|
|
|
protected function addUploadMethod(&$script)
|
|
{
|
|
foreach ($this->getFields() as $field) {
|
|
|
|
$camel_field = PropelUtils::camelCase($field);
|
|
|
|
$script.= <<<EOS
|
|
|
|
/**
|
|
* Upload the $field field
|
|
*
|
|
* @return void
|
|
*
|
|
*/
|
|
public function upload$camel_field()
|
|
{
|
|
if (null === \$this->$field && !\$this->delete_$field && null !== \$this->rollback_$field) {
|
|
\$this->$field = \$this->rollback_$field; // keep the file
|
|
|
|
return true;
|
|
}
|
|
|
|
if (null === \$this->$field || !is_object(\$this->$field)) {
|
|
return true; // no file to upload
|
|
}
|
|
|
|
//Delete old file on overload
|
|
\$this->remove$camel_field();
|
|
|
|
\$filename = \$this->getNewFilename(\$this->{$field}->guessExtension());
|
|
|
|
\$this->{$field}_file = \$this->{$field};
|
|
|
|
\$this->has_uploaded_$field = true;
|
|
|
|
\$this->$field = \$filename;
|
|
}
|
|
|
|
EOS;
|
|
}
|
|
}
|
|
|
|
protected function addSaveFileMethod(&$script)
|
|
{
|
|
$i18n = '';
|
|
if ($this->getTable()->hasColumn('locale')) {
|
|
$i18n = '.DIRECTORY_SEPARATOR.$this->locale';
|
|
}
|
|
|
|
foreach ($this->getFields() as $field) {
|
|
|
|
$camel_field = PropelUtils::camelCase($field);
|
|
|
|
$script.= <<<EOS
|
|
|
|
/**
|
|
* Save the file link to the $field field
|
|
*
|
|
* @return void
|
|
*
|
|
*/
|
|
public function save{$camel_field}File()
|
|
{
|
|
if (\$this->hasUploaded{$camel_field}()) {
|
|
\$this->{$field}_file->move(\$this->getUploadDir('$field')$i18n, \$this->{$field});
|
|
}
|
|
}
|
|
|
|
EOS;
|
|
}
|
|
}
|
|
|
|
protected function addRemoveMethod(&$script)
|
|
{
|
|
$i18n = '';
|
|
if ($this->getTable()->hasColumn('locale')) {
|
|
$i18n = '.DIRECTORY_SEPARATOR.$this->locale';
|
|
}
|
|
|
|
foreach ($this->getFields() as $field) {
|
|
|
|
$camel_field = PropelUtils::camelCase($field);
|
|
|
|
$script.= <<<EOS
|
|
|
|
/**
|
|
* Remove the $field file present in 'rollback_$field'
|
|
*
|
|
* @return void
|
|
*
|
|
*/
|
|
public function remove$camel_field()
|
|
{
|
|
if (!empty(\$this->rollback_$field)) {
|
|
\$file = \$this->getUploadDir('$field')$i18n.DIRECTORY_SEPARATOR.\$this->rollback_$field;
|
|
|
|
if (file_exists(\$file) && is_file(\$file)) {
|
|
unlink(\$file);
|
|
}
|
|
}
|
|
}
|
|
|
|
EOS;
|
|
}
|
|
}
|
|
|
|
protected function addGetterAsFile(&$script)
|
|
{
|
|
foreach ($this->getFields() as $field) {
|
|
$getter = $this->getColumnGetter($field);
|
|
|
|
$camel_field = PropelUtils::camelCase($field);
|
|
|
|
$script.= <<<EOS
|
|
|
|
/**
|
|
* Return the \$field value as File object
|
|
*
|
|
* @return \Symfony\Component\HttpFoundation\File\File
|
|
*
|
|
*/
|
|
public function ${getter}AsFile()
|
|
{
|
|
\$v = \$this->getWebPathFor$camel_field();
|
|
|
|
if (!empty(\$v) && file_exists(\$v) && is_file(\$v)) {
|
|
return new \Symfony\Component\HttpFoundation\File\File(\$v);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
EOS;
|
|
}
|
|
}
|
|
|
|
protected function addDeleteMethod(&$script)
|
|
{
|
|
foreach ($this->getFields() as $field) {
|
|
|
|
$camel_field = PropelUtils::camelCase($field);
|
|
|
|
$script.= <<<EOS
|
|
|
|
public function setDelete$camel_field(\$v)
|
|
{
|
|
\$this->delete_$field = \$v;
|
|
}
|
|
|
|
public function getDelete$camel_field()
|
|
{
|
|
return \$this->delete_$field;
|
|
}
|
|
|
|
EOS;
|
|
}
|
|
}
|
|
|
|
protected function addHasUploadedFieldMethod(&$script)
|
|
{
|
|
foreach ($this->getFields() as $field) {
|
|
|
|
$camel_field = PropelUtils::camelCase($field);
|
|
|
|
$script.= <<<EOS
|
|
|
|
public function hasUploaded$camel_field()
|
|
{
|
|
return \$this->has_uploaded_$field;
|
|
}
|
|
|
|
EOS;
|
|
}
|
|
}
|
|
|
|
protected function addWebPathMethod(&$script)
|
|
{
|
|
$i18n = '';
|
|
if ($this->getTable()->hasColumn('locale')) {
|
|
$i18n = '.DIRECTORY_SEPARATOR.$this->locale';
|
|
}
|
|
|
|
foreach ($this->getFields() as $field) {
|
|
|
|
$camel_field = PropelUtils::camelCase($field);
|
|
|
|
$script.= <<<EOS
|
|
|
|
public function getWebPathFor$camel_field()
|
|
{
|
|
return null === \$this->$field ? null : \$this->getUploadDir('$field')$i18n.DIRECTORY_SEPARATOR.\$this->$field;
|
|
}
|
|
|
|
EOS;
|
|
}
|
|
}
|
|
|
|
protected function addI18nWebPathMethod(&$script)
|
|
{
|
|
if ($this->getTable()->hasBehavior('i18n')) {
|
|
foreach ($this->i18n_upload_fields as $field) {
|
|
|
|
$camel_field = PropelUtils::camelCase($field);
|
|
|
|
$script.= <<<EOS
|
|
|
|
public function getWebPathFor$camel_field()
|
|
{
|
|
return \$this->getCurrentTranslation()->getWebPathFor$camel_field();
|
|
}
|
|
|
|
EOS;
|
|
}
|
|
}
|
|
}
|
|
|
|
protected function addSettersRollbacks(&$script)
|
|
{
|
|
$default = 'null';
|
|
|
|
foreach ($this->getFields() as $field) {
|
|
$rollback = sprintf("\$this->rollback_%s", $field);
|
|
$setter = $this->getColumnSetter($field);
|
|
$getter = $this->getColumnGetter($field);
|
|
|
|
$patterns = array(
|
|
"public function $setter(\$v)\n {",
|
|
"public function $setter(\$v)\n {",
|
|
'$v = (string) $v;',
|
|
);
|
|
|
|
$replace = "public function $setter(\$v)\n {
|
|
if (!isset($rollback)) {
|
|
$rollback = $default;
|
|
}
|
|
|
|
$rollback = \$this->$getter();\n";
|
|
|
|
$script = str_replace($patterns, array($replace, $replace, '// $v = (string) $v;'), $script);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public function staticAttributes()
|
|
{
|
|
$script = '';
|
|
$dirs = var_export($this->dirs, true);
|
|
$upload = sprintf("protected static \$uploadDirs = %s;%s", $dirs, PHP_EOL.PHP_EOL);
|
|
if (!empty($this->dirs)) {
|
|
$script .= <<<EOS
|
|
$upload
|
|
EOS;
|
|
}
|
|
|
|
return $script;
|
|
}
|
|
|
|
public function staticMethods()
|
|
{
|
|
$script = '';
|
|
|
|
if (empty($this->dirs)) {
|
|
return $script;
|
|
}
|
|
|
|
$script.= <<<EOS
|
|
|
|
/**
|
|
* Return the upload dir of \$field field
|
|
*
|
|
* @return string
|
|
*
|
|
*/
|
|
public static function getUploadDir(\$field)
|
|
{
|
|
return self::\$uploadDirs[\$field];
|
|
}
|
|
|
|
EOS;
|
|
|
|
return $script;
|
|
}
|
|
|
|
}
|