PhpSpreadsheet cell validation rules to disallow invalid entry - php

I am using PhpSpreadsheet within a Laravel app to output a spreadsheet that needs fairly strict controls around it in order to allow that same spreadsheet to be input back into the app after data has been entered.
I can control the data types and even have a nice pop-up message when a user enters an incorrect type such as this:
However, once the user clicks OK or Cancel, the incorrectly formatted text is allowed to remain in the cell. Is there a way to not only flag it for the user, but disallow the incorrect entry altogether?
Current example code:
if($sub['type'] === 'date') {
$ws->getStyle('C' . $row)->getNumberFormat()->setFormatCode(
\PhpOffice\PhpSpreadsheet\Style\NumberFormat::FORMAT_DATE_DMYSLASH
);
$objValidation = $ws->getCell('C' . $row)->getDataValidation();
$objValidation->setType(\PhpOffice\PhpSpreadsheet\Cell\DataValidation::TYPE_DATE);
$objValidation->setErrorStyle(\PhpOffice\PhpSpreadsheet\Cell\DataValidation::STYLE_INFORMATION);
$objValidation->setAllowBlank(true);
$objValidation->setShowInputMessage(true);
$objValidation->setShowErrorMessage(true);
$objValidation->setShowDropDown(true);
$objValidation->setErrorTitle('Input error');
$objValidation->setError('Please enter a date in the format d/m/yy only.');
}
I'm guessing I've missed something in the PhpSpreadsheet manual? I've looked into the base code on some of the methods like setAllowBlank, but I'm likely not looking in the right place.

I still couldn't find this in the docs (though I'm sure it is there somewhere). But once I was able to figure out where to look in the PhpSpreadsheet code, I found it. Very elegant solution from PhpSpreadsheet... I just couldn't see it in the area of base code I was looking into!
Easy fix, change one word:
$objValidation->setErrorStyle(\PhpOffice\PhpSpreadsheet\Cell\DataValidation::STYLE_INFORMATION);
Becomes:
$objValidation->setErrorStyle(\PhpOffice\PhpSpreadsheet\Cell\DataValidation::STYLE_STOP);
The big '!' on the popup gave me a clue to look at their style code rather than commands code. This brings up the same box, but with an 'X' and prevents changing the cell if not valid, which is exactly what I wanted.
Hopefully helps someone else in future.

Why not blanking the cell after validation error there is an isValid function. The code can look like:
if(! PhpOffice\PhpSpreadsheet\Cell\DataValidator::isValid($yourCell)){
$yourCell->setValue("");
}

Related

Enter a code to go to a specific page

I want to use an idea that I have seen on another website where I enter a "keyword", press Enter, and it then takes the client to a specific page or website.
I have seen something like this on http://qldgov.remserv.com.au, On the right side there is a field called "My Employer", type in "health" for example and you will be provided with relevant content.
Essentially I have client branded mini sites where we want to assign a "keyword" for each client brand so all of their employees will be able to go to their site entering this one keyword without all of them having individual logins. I want to be able to link to a URL that I can define in some manner.
I have looked at the source code of the site mentioned above and see they are using a form but I am not sure how they have assigned the keywords or if its even possible to do this without a database or anything like that. Trying to keep it as simple as possible as I am not a PHP/Java expert by any means.
Any help would be appreciated, even if its not code but an idea of the direction I need to go in to make this work. Thanks in advance!! :-)
The easiest way in my eyes would be to define an array that contains all of the keywords and respective urls client side (in JS). For example:
​var array = { 'health' : '/health.php', 'sport' : '/swimming.php' };
You would then get the user input on onSubmit and if it exists modify the window.location appropriately.
if ( array[user_input] !== undefined ) {
window.location = array[user_input];
}
else {
alert ( 'not found' );
}
If the user supplied health they will be redirected to /health.php, if they supply sport they will be redirected to /swimming.php (JSFiddle). Alternatively you can use server-side (PHP, JAVA) to handle the request but this may not be worth the effort.
Goodluck.
By using php (rather than javascript), you're not relying on javascript + making it seo friendly.
Firstly you're going to need either some sort of database or a list of keywords/urls
$keywords = array('keyword1' => 'path/to/load.php', 'another keyword' => 'another/path');
Then you'll need a basic form
<form action="loadkeyword.php">
<input name="query">
<button type="submit">Go</button>
</form>
Then in loadkeyword.php
$keywords = array('keyword1' => 'path/to/load.php', 'another keyword' => 'another/path');
$query = $_GET['query'];
if (isset($keywords[$query])) {
$url = $keywords[$query];
header("HTTP/1.0 301 Moved Permanently");
header('location: '.$url);
exit;
} else {
header("HTTP/1.1 404 Not Found");
die('unable to locate keyword');
}
If you have a large list of keywords, I would suggest using a database instead of an array to keep track of your keywords.
The site you link to is doing it server-side, either via a keyword-list that matches content or a search function (I suspect the latter).
There are a few different ways you could achieve your goal, all of them to do with matching keywords to content and then redirecting, either with an array, a list, or a database - the principle will be the same.
However, I would respectfully suggest this may not be the best solution anyway. My reasoning is that (based upon the example you give) you're effectively making your users guess which keyword matches which minisite (even if you have many keywords for each site). Why not just have some kind of menu to choose from (i.e. a selector with a list of minisites)?

I need help getting recaptcha to work

I recenlty had a site designed for me, but my dev used a really crappy generic captcha that fails half the time. I'm trying to replace it using a recaptcha, but I'm having trouble. I cannot figure out which *.php is used for 'processing' and which is used for the 'form'.
I didn't want to post the whole code, so here it is:
This is the 'form' page, as it has the form fields and etc embedded:
http://dl.dropbox.com/u/45666699/formcode.txt
Can someone please take a look at this code and tell me where I should put the private code for recaptcha? Also, how do I disable the "random_number" captcha that is already installed? Thanks!
the code for your existing captcha is on line 295, 296 and 297
require_once('recaptchalib.php');
$publickey = "6LfIUdISAAAAAKguxgdPCjZ6-OkVeu5tmcBaa7ug"; // you got this from the signup page
echo recaptcha_get_html($publickey);
Well you'll need the private key when you're trying to validate that the correct captch was entered (i.e. at the point where you're handling the form submission)
Which by looking at your code should start immediately after line 4
Using a project i did a while back, you would have something like so...
$recaptcha_error = NULL;
//set it to NULL initially
if(isset($_POST["btnsend"])){
include_once(INCLUDES_FOLDER."recaptcha-php-1.11/recaptchalib.php");
$resp = recaptcha_check_answer(RECAPTCHA_PRIVATE_KEY,$_SERVER["REMOTE_ADDR"],$_POST["recaptcha_challenge_field"],$_POST["recaptcha_response_field"]);
if($resp->is_valid){
//captch was gotten correctly
//continue with your normal code processing here
} else {
//wrong input -- captch was invalid -- give the person the error response
//mine is as below -- my usual way :)
$response = array(array("Something seems to be wrong with the captcha!","Please check that you entered it correctly or check the returned error message"),false,"w");
$recaptcha_error = $resp->error;
//make sure to do the above so u can use it when generating the captcha display
}
}
//You got the recaptch error (or left it as NULL above so you could do this)
//when generating your captch display as done on your lines 295, 296, 297
include_once(INCLUDES_FOLDER."recaptcha-php-1.11/recaptchalib.php");
echo recaptcha_get_html(RECAPTCHA_PUBLIC_KEY,$recaptcha_error);
Hope this helps (even if a little) :)
Cheers

In Drupal 7, how can I alter the contents of a submitted form before the values are validated?

I would like to do something roughly analogous (but not exactly identical) to the following: I want to create a Person content type, which has an SSN field. I would like to store the SSN field as an integer, but allow the user to input the number as 123-45-6789. This means that before validation triggers, stating that "123-45-6789" is invalid input, I would like to remove the dashes and treat this as an integer.
I've tried to use both a #value_callback function, as well as a non-default validation function. The problem then is that although I can force the value to be validated, the unchanged value is what is passed to the db for insertion, which fails. In example, this means that although I can force "123-45-6789" to be recognized by Drupal as "123456789", the database is still being passed "123-45-6789", which of course fails.
The one obvious solution would be altering this via client side javascript, before the value is even submitted to the webserver. I would strongly prefer to avoid this route.
Apologies if I've misunderstood but you should just be able to do something like this:
function my_validation_handler(&$form, &$form_state) {
if (passes_ssn_validation($form_state['values']['SSN'])) {
// Changing the value in $form_state here will carry on over to the submission function
$form_state['values']['SSN'] = convert_to_db_format($form_state['values']['SSN']);
}
else {
form_set_error('SSN', 'The SSN was invalid');
}
}
Then you'd attach that validation function using $form['#validate'][] = 'my_validation_handler' in either your form build or form_alter function.
Hope that helps
you should use hook_node_presave(). It allows you to change the values of different fields before they are inserted to the database. Here's the official documentation:
http://api.drupal.org/api/drupal/modules--node--node.api.php/function/hook_node_presave/7
Hope this can help :)

How can I write this Drupal snippet more efficiently?

I'm working on a patch to submit to the Registration Code module for Drupal. In short, is there a more efficient way to write the code below?
if (module_exists('regcode_voucher')) {
$cnfg = variable_get('regcode_voucher_display', array('regform' => 'regform'));
if (empty($cnfg['regform'])) {
return;
}
}
It seems like I should be able to reduce it to one if statement with && combining two conditions, but I haven't found the syntax or the necessary php array function that would allow me to do that.
In case some context helps, the regcode_voucher sub-module allows users to enter their registration code on the user edit page. On our sites, after a "beta" period, we want to simplify the registration form by removing the registration code field; but we'd like users to still be able to enter the code on their account edit page. The code above is part of a patch that allows the regcode's hook_user changes to be bypassed.
Code looks like good, what efficient do you want? Little changes may be:
if (module_exists('regcode_voucher')) {
$cnfg = variable_get('regcode_voucher_display', null);
if ($cnfg) {
// do your actions
}
}
And I don't recommend to merge if..., code should be clear and simpler to understand. If you merge these for optimizing, you win "tiny" milliseconds for real-live processors, but lost your clean code.
Why are you returning an array from variable_get if the variable is not found? variable_get will always return a string or a serialized array (that needs to be unserialized). If I'm missing something, you can use array_key_exists('regcode', variable_get(...)) to check for the array key.
This should work... note returning "false" from variable_get as a default if the variable is not found, which will cause the if conditions to not match. I personally find this more readable than nested if statements (for 3+ conditions I'd nest, though).
if( module_exists('regcode_voucher') && variable_get('regcode_voucher_display', false) ) {
// stuff
}

DotNetNuke, PHP, Simulating a remote postback using curl

I have a page in DNN like:
http://nolimitswebdesign.com.dnnmax.com/test/tabid/57/ctl/Edit/mid/374/Default.aspx
I need to send a post request to that page using PHP+Curl which modifies the content of text area and saves it (like as if someone modified it manually and clicked the update button on that page). I doubt that with DNN it might not be possible. Please advise.
Here is how I would approach the problem the same general technique will work on any website. In this context DNN is just an average ASP.Net website. First look at the javascript that runs when update is clicked:
__doPostBack('dnn$ctr374$EditHTML$cmdUpdate','')
Find the __doPostBack method:
function __doPostBack(eventTarget, eventArgument) {
if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
theForm.__EVENTTARGET.value = eventTarget;
theForm.__EVENTARGUMENT.value = eventArgument;
theForm.submit();
}
}
This is the standard doPostBack() method used in many ASP.Net forms. From this you can see that you want to fill in the __EVENTTARGET and __EVENTARGUEMENT hidden fields with the appropriate values from the method call and submit the form.
Of course you also need to fill in the data you actually want to save into the input control for the text box. It will probably be easier to do this if you use the basic text box mode of the HTML module, then you just need to set the value of a textarea rather than figure out where to insert the value in the fckEditor, and the technique will be still work if the site is configured to use the Telerik provider instead of the fck provider.
One thing to watch out for is that the control name may change from time to time, so you need to be sure you are reading the correct ids for the event target, and textarea not just hard coding something.

Categories