Monday, May 14, 2012

Re: CakePHP (2.1) Media Plugin - Multi File Upload

Just thought I'd post my slightly cleaner solution to this which makes
use of a modified version of the attachments element in the media
plugin. This allows you to use the attachment multiple times in a form
for when you have different groups of attachments i.e. photos, files,
videos etc. I'm no programmer, just a designer so there's probably a
better way to do it but I don't know it :)

To save me editing too much I'll just use my example of a
ProjectProfile model:

ProjectProfile.php >

<?php
App::uses('AppModel', 'Model');
class ProjectProfile extends AppModel {

var $name = 'ProjectProfile';
var $useDbConfig = 'default';
var $useTable = 'project_profiles';
var $actsAs = array('Media.Transfer',
'Media.Generator'
);

public $belongsTo = array(
'Project' => array(
'className' => 'Project',
'foreignKey' => 'pjID'
//'conditions' => '',
//'fields' => '',
//'order' => ''
)
);

var $hasMany = array(
'Photo' => array(
'className' => 'Media.Attachment',
'order' => 'Photo.basename, Photo.id',
'foreignKey' => 'foreign_key',
'conditions' => array('Photo.model' => 'ProjectProfile',
'Photo.group' => 'Photo'),
'dependent' => true),
'Attachment' => array(
'className' => 'Media.Attachment',
'order' => 'Attachment.basename, Attachment.id',
'foreignKey' => 'foreign_key',
'conditions' => array('Attachment.model' =>
'ProjectProfile', 'Attachment.group' => 'Attachment'),
'dependent' => true)
);
}


ProjectProfilesControler.php >

<?php
App::uses('AppController', 'Controller');
class ProjectProfilesController extends AppController {

....

public function admin_edit($id = null) {
$this->ProjectProfile->id = $id;
if (!$this->ProjectProfile->exists()) {
throw new NotFoundException(__('Invalid project profile'));
}
if ($this->request->is('post') || $this->request->is('put')) {
//convert cakephp html5 file upload data array to media plugin
required format
$model = Inflector::classify($this->params['controller']);
foreach ($this->request->data[$model]['assocAlias'] as
$assocAlias) {
$i = 0;
foreach ($this->request->data[$model][$assocAlias.'files'] as
$file) {
$this->set($this->request->data[$assocAlias][$i]['model'] =
$model);
$this->set($this->request->data[$assocAlias][$i]['group'] =
strtolower($assocAlias));
$this->set($this->request->data[$assocAlias][$i]['file'] =
$this->request->data[$model][$assocAlias.'files'][$i]);
$i++;
}
}
if ($this->ProjectProfile->saveAll($this->request->data)) {
$this->Session->setFlash(__('The project profile has been
saved'));
$this->redirect(array('action' => 'admin_edit', $id));
} else {
$this->Session->setFlash(__('The project profile could not be
saved. Please, try again.'));
}
} else {
$this->request->data = $this->ProjectProfile->read(null, $id);
}
$projects = $this->ProjectProfile->Project->find('list',
array('fields' => array('Project.pjID', 'Project.pntitle')));
$this->set(compact('projects'));
}

....

?>

Then in the view/form:
admin_edit.php >
<div class="projectProfiles form">
<?php echo $this->Form->create('ProjectProfile',
array('type'=>'file'));?>
<fieldset>
<legend><?php echo __('Admin Edit Project Profile'); ?></legend>
<?php
echo $this->Form->input('id');
echo $this->Form->input('pjID', array('label' => 'Project',
'options' => $projects));
echo $this->Form->input('description');
echo $this->Form->input('longitude');
echo $this->Form->input('latitude');
echo $this->Form->input('major', array('label' => 'Major Project'));
//The num variable below is just used in the media
attachments element so the controller can loop through the array, so
just make sure you give each of the nums a sequential numerical order.
The assocAlias just sets the group of attachments.
echo $this->element('Media.attachments', array('model' =>
'ProjectProfile', 'assocAlias' => 'Photo', 'num' => 0));
echo $this->element('Media.attachments', array('model' =>
'ProjectProfile', 'assocAlias' => 'Attachment', 'num' => 1));
?>
</fieldset>
<?php echo $this->Form->end(__('Submit'));?>
</div>


Then this is a slightly modified version of the media attachment
element, replace with this version...
/Plugin/Media/View/Elements/attachment.php
<?php
if (!isset($this->Media) || !is_a($this->Media, 'MediaHelper')) {
$message = 'Attachments Element - The media helper is not loaded but
required.';
trigger_error($message, E_USER_NOTICE);
return;
}

if (!isset($previewVersion)) {
$previewVersion = 's';
}

/* Set $assocAlias and $model if you're using this element multiple
times in one form */

if (!isset($assocAlias)) {
$assocAlias = 'Attachment';
} else {
$assocAlias = Inflector::singularize($assocAlias);
}

if (!isset($model)) {
$model = $this->Form->model();
}

$modelId = $this->Form->value($this->Form->model().'.id');

if (isset($this->request->data[$assocAlias][0]['basename'])) {
array_unshift($this->request->data[$assocAlias],array());
}

if (!isset($title)) {
//$title = sprintf(__('%s', true),
Inflector::pluralize($assocAlias));
$title = Inflector::pluralize($assocAlias);
}

?>
<div class="attachments element">
<?php echo $title ?>
<!-- New Attachment -->
<div class="new" id="<?php echo $assocAlias ?>">
<?php
echo $this->Form->hidden($model.'.assocAlias.'.$num, array('value'
=> $assocAlias));
echo $this->Form->input($assocAlias.'files.', array(
'type' => 'file', 'multiple',
'error' => array(
'error' => __('An error occured while transferring the
file.', true),
'resource' => __('The file is invalid.', true),
'access' => __('The file cannot be processed.', true),
'location' => __('The file cannot be transferred from or to
location.', true),
'permission' => __('Executable files cannot be uploaded.', true),
'size' => __('The file is too large.', true),
'pixels' => __('The file is too large.', true),
'extension' => __('The file has the wrong extension.', true),
'mimeType' => __('The file has the wrong MIME type.', true),
)));

?>

</div>
<?php


?>

<!-- Existing Attachments -->
<div class="existing">
<?php if (isset($this->data[$assocAlias])): ?>
<?php for ($i = 1; $i < count($this->data[$assocAlias]); $i++): ?>
<div>
<?php
$item = $this->data[$assocAlias][$i];

echo $this->Form->hidden($assocAlias . '.' . $i . '.id',
array('value' => $item['id']));
echo $this->Form->hidden($assocAlias . '.' . $i . '.model',
array('value' => $model));
echo $this->Form->hidden($assocAlias . '.' . $i . '.group',
array('value' => $item['group']));
echo $this->Form->hidden($assocAlias . '.' . $i . '.dirname',
array('value' => $item['dirname']));
echo $this->Form->hidden($assocAlias . '.' . $i . '.basename',
array('value' => $item['basename']));
echo $this->Form->hidden($assocAlias . '.' . $i . '.alternative',
array('value' => $item['alternative']));

if ($file = $this->Media->file("{$item['dirname']}/
{$item['basename']}")) {
$url = $this->Media->url($file);
$size = $this->Media->size($file);
$name = $this->Media->name($file);

echo $this->Media->embed($this->Media->file("{$previewVersion}/
{$item['dirname']}/{$item['basename']}"), array(
'restrict' => array('image')
));

if (isset($this->Number)) {
$size = $this->Number->toReadableSize($size);
} else {
$size .= ' Bytes';
}

printf(
'<span class="description">%s&nbsp;(%s/%s) <em>%s</em></span>',
$url ? $this->Html->link($item['basename'], $url) :
$item['basename'],
$name,
$size,
$item['alternative']
);
}

echo $this->Form->input($assocAlias . '.' . $i . '.alternative',
array('label' => 'Description', 'value' => $item['alternative']));

echo $this->Form->input($assocAlias . '.' . $i . '.delete', array(
'label' => __('Release', true),
'type' => 'checkbox',
'value' => 0
));
?>
</div>
<?php endfor ?>
<?php endif ?>
</div>
</div>

Hope that helps somebody.

--
Our newest site for the community: CakePHP Video Tutorials http://tv.cakephp.org
Check out the new CakePHP Questions site http://ask.cakephp.org and help others with their CakePHP related questions.


To unsubscribe from this group, send email to
cake-php+unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/cake-php

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]

<< Home


Real Estate