I'm trying to implement some fairly simple image uploading using the MeioUpload behaviour in CakePHP 1.3, but I can't for the life of me get it to work. When I try to save $this->data in my controller, it tries to save a regular file array (for lack of a better word) rather than just the filename.
Here's what I'm doing:
I've put meio_upload.php into /app/models/behaviors
In my model, I'm doing the following:
var $actsAs = array(
'MeioUpload.MeioUpload' => array(
'filename' => array(
'dir' => 'img{DS}upload{DS}brawlers',
'allowedMime' => array('image/png'),
'allowedExt' => array('.png', '.PNG'),
'zoomCrop' => false,
'thumbsizes' => array(
'normal' => array(
'width' => 150,
'height' => 150
)
),
'default' => 'default.png',
'length' => array(
'minWidth' => 100,
'minHeight' => 100,
'maxWidth' => 150,
'maxHeight' => 150
)
)
)
);
In my view, I've got the following form:
<?php
echo $this->Form->create('Brawler', array('type' => 'file'));
echo $this->Form->input('name', array(
'label' => 'Name',
'maxLength' => '45'
)
);
echo $this->Form->input('comment', array(
'label' => 'Description',
'rows' => '3'
)
);
echo $this->Form->input('author', array(
'label' => 'Your name)',
'maxLength' => '45'
)
);
echo $this->Form->input('email', array(
'label' => 'Email (will not be shown)',
'maxLength' => '45'
)
);
echo $this->Form->input(
'filename',
array(
'between'=>'<br />',
'type'=>'file',
'label' => 'Image (Max 2mb, 150x150 pixels, .png)'
)
);
echo $this->Form->end('Submit');
?>
And finally my add action in the associated controller looks like this:
function add() {
if (!empty($this->data)) {
$this->Brawler->create();
if($this->Brawler->save($this->data)) {
$this->Session->setFlash('The brawler has been saved', true);
$this->redirect(array('action'=>'index'));
} else {
$this->Session->setFlash('The Brawler could not be saved. Please try again.', true);
debug($this->data);
debug($this->validationErrors);
die();
//$this->redirect(array('action'=>'add'));
}
}
}
For posterity, here's my table design:
delimiter $$
CREATE TABLE `brawlers` (
`id` int(11) NOT NULL,
`name` varchar(45) NOT NULL,
`date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`comment` text,
`email` varchar(45) NOT NULL,
`author` varchar(45) NOT NULL,
`filename` varchar(100) NOT NULL,
PRIMARY KEY (`id`),
) ENGINE=MyISAM DEFAULT CHARSET=utf8$$
When I try to submit my form, this is the output I get:
app/controllers/brawlers_controller.php (line 37)
Array
(
[Brawler] => Array
(
[name] => Viking
[comment] => Herp. This is a description.
[author] => Me
[email] => me#gmail.com
[filename] => Array
(
[name] => 5.png
[type] => image/png
[tmp_name] => /storage/configuration/upload_tmp_dir/phpEF2okD
[error] => 0
[size] => 15863
)
)
)
app/controllers/brawlers_controller.php (line 37)
Obviously, this fails when it tries to save an array to the filename field. The image is never saved in the specified upload directory either. It seems like the meioupload behavior is never actually used. How can I verify this?
You'll have to excuse the mass of code that I've posted, but I figure it's better that I show you everything than to have you guess at what I may be doing. If someone can spot the error, that would save me many hours of pulling my hair.
Hey i have answer for ur Query
That is u have to make anther variable Say
$d1 and copy $this->date array into that array like below
$d1['brawlers']['name'] = $this->data['brawlers']['name'];
all ur variables
$d1['brawlers']['filename'] = $this->data['brawlers']['filename']['name'];
and then save it like $this->brawlers->save($d1);
I'm NOT PHP guy, but I had to use the CakePHP and Meio.Upload some time ago.
AFAIK you need 4 fields in your database for image:
filename (you can change name of this one in
settings)
dir
mimetype
filesize
Judging on your error and db schema I would say you are missing some of the fields.
Edit:
See the documentation
I had the same problem, the MeioUpload version your are using is incompatible with your version of Cake. I ended using version 2.3 of MeioUpload.
Related
Add an extra field for fileupload. But the data getting in template is a set of special characters. How to get the original path?
My code:
$GLOBALS['TL_DCA']['tl_news']['fields']['image'] = array
(
'label' => &$GLOBALS['TL_LANG']['tl_news']['quoteperson_image'],
'exclude' => true,
'filter' => true,
'inputType' => 'fileTree',
'eval' => array('tl_class' => 'clr','files' => true,'fieldType' =>'checkbox',),
'sql' => "blob NULL",
);
The data returned by the fileTree widget is a binary UUID. In order to get the original path you can do the following for example:
$objFile = \Contao\FilesModel::findByUuid($uuid);
$strPath = $objFile->path;
I need to launch a .bat file that creates a php file, containing this text:
<?php
$_mail_mailSpooler = array (
'classname' => 'mail_mailSpooler',
'from' => 'test#test.com',
'array_indirizzi_mail' =>
array (
0 => ‘lol#hotmail.com’,
'testo_mail' => ‘prova’,
'filename_html' => NULL,
'oggetto_mail' => ‘prova’,
'elenco_allegati' => '',
'forza_mail_txt' => 0,
'asl_logger' => '',
'log_identifier' => NULL,
'log_in_web' => 0,
'log_str' => '',
'nome_file_dump' => '../mailSpooler/mail_incoming/maildda2.php',
);
I have tried echo " (test)" >gnagna.php
but it doen't work.
any suggestion please?
thanks
use type instead of echo - echo's only supposed to give user feedback, file reading and writing is properly done by type. Have a look at http://www.robvanderwoude.com/allhelpw2ksp4_en.php#TYPE for more
sorry, but i'm not already able to launch my php with right code.
i've tried type <?php
$_mail_mailSpooler = array (
'classname' => 'mail_mailSpooler',
'from' => 'test#test.com',
'array_indirizzi_mail' =>
array (
0 => ‘lol#hotmail.com’,
'testo_mail' => ‘prova’,
'filename_html' => NULL,
'oggetto_mail' => ‘prova’,
'elenco_allegati' => '',
'forza_mail_txt' => 0,
'asl_logger' => '',
'log_identifier' => NULL,
'log_in_web' => 0,
'log_str' => '',
'nome_file_dump' => '../mailSpooler/mail_incoming/maildda2.php',
); C:\>test.php
but it doesn't work.
moreover your link says that this command displays the content of an existing file and i need to create a new one!
I had asked a question here a while back about setting up database populated dropdowns for SugarCRM. I received a really good answer and, after more php studies and a dev instance running, I decided to give it a shot. The instructions I followed can be found here. After I run the repair and rebuild, I would expect to see the custom field in my Fields list under the module in studio, but have not been able to find it. The module is named Makers (a1_makers as a database table). For good orders sake, there were no errors when I repaired/rebuilt after saving the files. Per the instructions, I first created a php file with a custom function to query the database (custom/Extension/application/Ext/Utils/getMakers.php):
<?php
function getMakers() {
static $makers = null;
if (!$makers){
global $db;
$query = "SELECT id, name FROM a1_maker";
$result = $db->query($query, false);
$accounts = array();
$accounts[''] = '';
while (($row = $db->fetchByAssoc($result)) !=null) {
$accounts[$row['id']] = $row['name'];
}
}
return $makers;
}
?>
Then, I set 'function' field in Vardefs to point to the function (custom/Extension/modules/Maker/Ext/Vardefs/makers_template.php):
<?php
$dictionary['Maker']['fields']['list_of_makers'] = array (
'name' => 'list_of_makers',
'vname' => 'LBL_MKRLST'
'function' => 'getMakers',
'type' => 'enum',
'len' => '100',
'comment' => 'List of makers populated from the database',
);
?>
Unfortunately, there are no errors and the repair/rebuild runs fine. I am just unable to see the custom field when I go into studio. Can anyone please help point out what I may be doing wrong?
I would recommend checking existence of newly created field 'list_of_makers' in cache/modules/Maker/Makervardefs.php file. If new field definition exists in that file, try add 'studio' => 'visible' to custom/Extension/modules/Maker/Ext/Vardefs/makers_template.php to get something like this:
<?php
$dictionary['Maker']['fields']['list_of_makers'] = array (
'name' => 'list_of_makers',
'vname' => 'LBL_MKRLST'
'function' => 'getMakers',
'type' => 'enum',
'studio' => 'visible'
'len' => '100',
'comment' => 'List of makers populated from the database',
);
Try to edit your custom/modules/Maker/metadata/editviewdefs.php manually and insert field definition by hand in proper place if everything above won't work.
$dictionary['Maker']['fields']['list_of_makers'] = array (
'name' => 'list_of_makers',
'vname' => 'LBL_MKRLST'
'function' => 'getMakers',
'type' => 'enum',
'studio' => 'visible'
'len' => '100',
'comment' => 'List of makers populated from the database',
'studio' => array(
'listview' => true,
'detailview' => true,
'editview' => true
),
);
Anyone able to offer some ideas on this? Basically the module I'm building has a form (as per function_email_solicitors_compose), and on submission we obviously route to form_emails_solicitors_compose_submit. Here I define a batch in $batch, and batch_set the aforementioned batch. The drupal documentation says I don't need to run batch_process() if it's called from within a form_submit, which this is, but I've tried with and without. All tests have shown that it gets as far as defining the batch but never goes any further than that. email_solicitors_batch_iteration never runs. Any ideas?
As an additional bit of info, batch_get then returns the following:
Array
(
[sets] => Array
(
[0] => Array
(
[sandbox] => Array
(
)
[results] => Array
(
)
[success] =>
[title] => Emailing.
[operations] => Array
(
[0] => Array
(
[0] =>
email_solicitors_batch_iteration
[1] => Array
(
[0] =>
[1] =>
)
)
)
[finished] => my_finished_callback
[init_message] => Initializing.<br/>
[progress_message] => Remaining
#remaining of #total.
[error_message] => An error has
occurred.
[total] => 1
)
)
)
The code:
function email_solicitors_compose(){
$form['email_solicitors_subject'] = array(
'#type' => 'textfield',
'#title' => t('Subject'),
'#description' => t('Enter the subject of your email'),
'#default_value' => 'Subject',
'#size' => 30
);
$form['email_solicitors_message'] = array(
'#type' => 'textarea',
'#title' => t('Message'),
'#description' => t('Write your message here. <strong>Please note that we will automatically add "Dear #name", which will be personalised to the solicitor.</strong>'),
'#default_value' => '',
);
$form['email_solicitors_submit'] = array(
'#type' => 'submit',
'#title' => t('Submit'),
'#description' => t('Sumbit this form.'),
'#default_value' => 'Submit',
);
return $form;
}//function email_solicitors_compose
function email_solicitors_compose_submit($form_state)
{
$batch = array(
'title' => t('Sending emails to solicitors'),
'operations' => array(
array('email_solicitors_batch_iteration', array())
),
'finished' => 'email_solicitors_batch_finished', //run this when we're finished
'init_message' => t('Preparing to send emails'), //initialisation message
'progress_message' => t('Sent #current out of #total messages.'),
'error_message' => t('Sorry, something went wrong when sending emails.'),
);// create batch array
$info=print_r($batch,TRUE);
drupal_set_message($info);
batch_set($batch);
batch_process();
}//function email_solicitors_compose_submit
function email_solicitors_batch_iteration(&$context)
{
// Initialize sandbox the first time through.
if (!isset($context['sandbox']['progress'])) {
$context['sandbox']['progress'] = 0;
$context['sandbox']['current_user_id'] = 0;
$context['sandbox']['max'] = db_result(db_query('SELECT COUNT(DISTINCT field_solicitor_email_value) FROM content_type_solicitor'));
}
$comment="On item ".$context['sandbox']['progress'];
drupal_set_message ($comment);
}//function email_solicitors_batch_iteration
function email_solicitors_batch_finished (&$context)
{
die ('woohoo we finished');
}
As an addition to the answer Clive has given, you could consider adding the "file" parameter to the batch-array. This will tell the API where the function is located.
Example:
$batch = array(
'title' => t('Sending emails to solicitors'),
'operations' => array(
array('email_solicitors_batch_iteration', array())
),
'finished' => 'email_solicitors_batch_finished', //run this when we're finished
'init_message' => t('Preparing to send emails'), //initialisation message
'progress_message' => t('Sent #current out of #total messages.'),
'error_message' => t('Sorry, something went wrong when sending emails.'),
'file' => drupal_get_path('module', '<module_name>').'/path_to_include_file.inc',
);
It worked for me :)
Just in case anyone is still struggling with this the previous two comments are incorrect, you do not need to explicitly set the $context['finished'] variable (see the examples module, batch_example).
The reason it's not working is simply because the batch operation function is in a file not included in the default Drupal bootstrap. If you move the batch operation function out of an include file and into the module file of an enabled module it will work.
Are you having a start of sign that the batch is beginning or just nothing happens?
You are missing two information in your batch operation callback: the increase of the progress and most importantly a statement to determine when the batch should over.
// Update our progress information.
$context['sandbox']['progress']++;
$context['sandbox']['current_node'] = $row['nid'];
$context['message'] = t('Calcul des votes pour %node', array('%node' => $row['title']));
if ($context['sandbox']['progress'] != $context['sandbox']['max']) {
$context['finished'] = $context['sandbox']['progress'] / $context['sandbox']['max'];
}
You do not need to call batch_process(), just batch_set() in a submit callback is everything you need. See for example http://api.worldempire.ch/api/privatemsg/privatemsg_filter--privatemsg_filter.admin.inc/function/privatemsg_filter_inbox_rebuid_form_submit/7-1.
And as Artusamak said, your batch implementation is incomplete and would result in a endless loop.
So I'm having trouble with unit testing CakePHP models. Simple stuff like writing tests that my validation rules are catching errors etc.
To begin with, I have a model called NewsItem. Its defined in my MySQL database using the following schema
CREATE TABLE news_items (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(140) NOT NULL,
body TEXT NOT NULL,
modified DATETIME DEFAULT NULL,
created DATETIME DEFAULT NULL
);
The model is following
<?php
class NewsItem extends AppModel {
var $name = 'NewsItem';
var $validate = array(
'title' => array(
'titleRule-1' => array(
'rule' => array('maxLength', 140),
'message' => 'News item\'s title\'s length exceeds limit of 140 characters'
),
'titleRule-2' => array(
'rule' => 'alphaNumeric',
'required' => true,
'message' => 'Cannot save news item without a title'
)
)
);
}
?>
And in my test case I have
// Validation lets All data good through
function testValidationAllowsNormalData()
{
$this->assertTrue($this->NewsItem->save(array('NewsItem' => array('title' => 'A news item', 'body' => 'Some news'))));
}
However I'm my test case fails. Any ideas, suggestions, comments?
The alphaNumeric validation rule only allows, well, alphanumeric characters, i.e. no spaces. So your test fails correctly.
I'm not hugely familiar with cakePHP, but wouldn't save attempt to persist to the database? That should not be in a unit test if that is the case...