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.
Related
I am trying to implement the 'InArray' validator in Zend 2 on a form and it keeps on returning invalid. Here is the code:
The Form Element setup:
$enquiryType = new Element\Select('enquiryType');
$enquiryType->setLabel('* What is your enquiry about?')
->setLabelAttributes(array('class' => 'sq-form-question-title'))
->setAttribute('class', 'sq-form-field required')
->setValueOptions($enquiryTypes);
The Filter/Validator setup:
$enquiryType = new Input('enquiryType');
$enquiryType->getValidatorChain()
->addByName('InArray', array('haystack' => $enquiryTypes));
And here is the array that gets passed into $enquiryTypes via the module.config.php file
'enquiryCategories' => array(
'empty_option' => 'Please select an option',
array(
'label' => 'General enquiries',
'options' => array(
'skype' => 'Skype with your library feedback',
'question' => 'Ask a question',
'feedback' => 'Library feedback',
'eresource' => 'Electronic resources (e.g. e-book, e-journal, database)',
'webbridge' => 'WebBridge Problems',
'dro' => 'DRO'
)
),
array(
'label' => 'Application to review',
'options' => array(
'10400' => 'I\'ve returned the item',
'10401' => 'I didn\'t know about overdue points but now I have some',
'10402' => 'Why did I get this invoice?',
'10403' => 'The item I borrowed is lost',
'10404' => 'The item I borrowed has been damaged',
'10405' => 'I never got/had the book',
'10406' => 'Other'
)
)
),
I have tried different variations of this (using the recursive validation also) but have not been able to work this out.
One thing that I'd try, is as follows:
$enquiryType = new Input('enquiryType');
$enquiryType->getValidatorChain()
->addByName('InArray', array('haystack' => $enquiryTypes['enquiryCategories']));
The reason I say that, is that it looks like you might be creating an array inside of the array perhaps. Unless I've misunderstood the description.
If that isn't working for you then maybe you might need to explore the Explode option as pointed out in the following question
ZF2: How do I use InArray validator to validate Multiselect form element?
Good luck.
I finally got a working solution for this. I feel there should be a better solution but I could not find one.
Here is the filter I used:
$enquiryType = new Input('enquiryType');
$enquiryType->getValidatorChain()
->addByName('InArray', array('haystack' => array_keys(
$enquiryTypes[0]['options']+$enquiryTypes[1]['options']
)));
$enquiryType->getFilterChain()
->attach(new Filter\StringToLower())
->attachByName('StripTags');
Basically I had to disect the array options into a straight associative array. As the array remains static in this instance then this works well.
If the data becomes dynamic then something more would be required (loop through and find the 'option' key, add children to filter array etc...)
I was recently brought on by a company that uses Quickbase. They have limited systems in place to talk to the Quickbase application, so I am trying to incorporate the PHP SDK in order to add/edit records in Quickbase using a front end designed by myself so customers can submit a form from the web into Quickbase.
I'm coming across a problem right away trying to get the SDK to even respond with something other than an error. Currently it doesn't respond with anything when trying to add a record.
I keep reading that a recent (~2-3 years ago) change has caused this to be a bit difficult to use.
below is my codesnippet from a php page called "addnewcustomer.php"
include_once('quickbase.php');
//my PHP SDK Options located inside quickbase.php
var $user_name = 'username'; // QuickBase user who will access the QuickBase
var $passwd = 'pw'; // Password of this user
var $db_id = 'dbid'; // Table/Database ID of the QuickBase being accessed
var $app_token = 'my app token';
var $xml = true;
var $user_id = '';
var $qb_site = "www.mycompany.quickbase.com";
var $qb_ssl = "https://www.mycompany.quickbase.com/db/";
var $ticketHours = 12;
$quickbase = new QuickBase('myusername', 'mypw', true, "dbid", "token", "realm", hour);
$fields = array(
array(
'fid' => '148',
'value' => $agentid), //agentid
array(
'fid' => '15',
'value' => $city), //city
array(
'fid' => '16',
'value' => $state), //state
array(
'fid' => '14',
'value' => $address), //address
array(
'fid' => '524',
'value' => $apt), //apt #
array(
'fid' => '17',
'value' => $zip), //zip code
array(
'fid' => '33',
'value' => $rentown), //rent/own
array(
'fid' => '28',
'value' => $first), //first name
array(
'fid' => '29',
'value' => $last), //last name
array(
'fid' => '21',
'value' => $email), //email
array(
'fid' => '18',
'value' => $phone) //phone
);
$quickbase->add_record($fields);
It currently responds with nothing, ie. blank response. If I change the realm with something inaccurate I get an error of "Fatal error: Uncaught exception 'Exception' with message 'String could not be parsed as XML'", which makes me think I have everything setup correctly.
What should a successful entry return? What am I doing wrong?
The add_record method should be returning an XML object. If you capture that object, you can check it to see if the API call was successful or if an error was returned. So, if you change your code to:
$results = $quickbase->add_record($fields);
print_r($results);
You'll get something you can understand. It's inelegant, but it will show you quickly if you're getting a response and if that response is an error. You should see something like this on success:
SimpleXMLElement Object ( [action] => API_AddRecord [errcode] => 0 [errtext] => No error [rid] => 81 [update_id] => 1436476140453 )
I am trying to parse an IPN callback from paypal. The type of payment is adaptive, so there is an array of transactions (even though I will only have 1).
Here is a sample IPN with some fields pruned for readability:
array (
'payment_request_date' => 'Fri Jan 30 22:28:54 PST 2015',
'verify_sign' => 'removed',
'transaction[0].id_for_sender_txn' => 'removed',
'transaction[0].receiver' => 'removed',
'cancel_url' => '#pruned',
'transaction[0].is_primary_receiver' => 'false',
'pay_key' => '#removed',
'action_type' => 'PAY',
'transaction[0].id' => 'id is here',
'transaction[0].status' => 'Completed',
'transaction[0].paymentType' => 'SERVICE',
)
I am trying to access the value of 'transaction[0].id' and cannot get it to dump. I have tried basically every possible way I can think of:
$id = $_POST['transaction'][0]['id'];
$id = $_POST['transaction[0].id'];
Also tried asking the array to a var and then using that:
$id = $array->transaction[0].id;
This should give you the info you need.
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
),
);
I have the multiCheckbox element on my form with the common callback validator.
Validator works ok, but error message contains duplicated strings, separated by semicolon instead of single message. If 2 checkboxes selected - the 2 error messages, if 4 - 4 error messages and so on.
Do you know how to modify the code in order to show only one single error message instead of duplicates?
$rolesElement = $form->getElement('role_ids');
$rolesElement->addValidator(new Zend_Validate_Callback(function ($value) use ($rolesElement, $administrator) {
if( *magicHere* ){
$rolesElement->clearErrorMessages();
$rolesElement->setErrorMessages(array('blablabla!'));
return false;
}
return true;
}));
You can always use setMessages() method of the Validator class you are using to set Custom Error Messages.
Here is my Code
$emailIdValidator->setMessages(array(
Zend_Validate_EmailAddress::DOT_ATOM => $this->coreUtils->getApplicationMessages("EMAIL_ERROR"),
Zend_Validate_EmailAddress::INVALID => $this->coreUtils->getApplicationMessages("EMAIL_ERROR"),
Zend_Validate_EmailAddress::INVALID_FORMAT => $this->coreUtils->getApplicationMessages("EMAIL_ERROR"),
Zend_Validate_EmailAddress::INVALID_HOSTNAME => $this->coreUtils->getApplicationMessages("EMAIL_ERROR"),
Zend_Validate_EmailAddress::INVALID_LOCAL_PART => $this->coreUtils->getApplicationMessages("EMAIL_ERROR"),
Zend_Validate_EmailAddress::INVALID_MX_RECORD => $this->coreUtils->getApplicationMessages("EMAIL_ERROR"),
Zend_Validate_EmailAddress::INVALID_SEGMENT => $this->coreUtils->getApplicationMessages("EMAIL_ERROR"),
Zend_Validate_EmailAddress::LENGTH_EXCEEDED => $this->coreUtils->getApplicationMessages("EMAIL_ERROR"),
Zend_Validate_EmailAddress::QUOTED_STRING => $this->coreUtils->getApplicationMessages("EMAIL_ERROR"),
));
$form = new Zend_Form ();
$form->addElement ('MultiCheckbox', 'name', array (
'label' => 'test',
'multioptions' => array (
1 => 'fake',
65 => 'dsa',
165 => 'dsa22'
)
));
$form->name->addValidator ('Callback', true, array (
'callback' => array (
$this,
'val'
),
'messages' => array (
'callbackValue' => 'Error in here'
)
));
In this case, the validating function should not add any error messages. Just a boolean value.
function val ($value, $values)
{
return false;
}
The problem is solved by the creation of my own custom validator based on Zend_Validate.