Gravity Forms: Multi-Page Form Validation - validation

I have a field 47 on Page 1 and a field 55 on Page 3 of a form. How do I create a gform_validation on Page 3 to prompt an error message when Field 47 < Field 55? The code below works for validation if both fields are on same page but it doesn't work for multi-page. Any idea plz?
Thanks!
// multi-page validation
add_filter( 'gform_validation', 'custom_validation' );
function custom_validation( $validation_result ) {
$form = $validation_result['form'];
// Financial Assets must be larger than Investment
if ( rgpost( 'input_47' ) < rgpost( 'input_55' ) ) {
// set the form validation to false
$validation_result['is_valid'] = false;
//finding Field with ID of 1 and marking it as failed validation
foreach( $form['fields'] as &$field ) {
//NOTE: replace 1 with the field you would like to validate
if ( $field->id == '34' ) {
$field->failed_validation = true;
$field->validation_message = 'Your Financial Assets (A) cannot be lower than your investment with us. Please fix the discrepancy.';
break;
}
}
}
//Assign modified $form object back to the validation result
$validation_result['form'] = $form;
return $validation_result;
}
I found the following information on their documentation however I'm not sure how to implement it inside the code above. Any clue? Thanks alot!
// 3 - Get the current page being validated
$current_page = rgpost( 'gform_source_page_number_' . $form['id'] ) ? rgpost( 'gform_source_page_number_' . $form['id'] ) : 1;

First, you can get the submitted page via the GFFormDisplay::get_source_page( $form_id ) method.
There are a few different ways this could be done. For simplicity, I would just bypass validation until your desired page is submitted. To do that, just add something like this:
if( GFFormDisplay::get_source_page( $form_id ) >= 3 ) {
return $validation_result;
}
...after this line:
$form = $validation_result['form'];
This would only run this validation on pages greater than page 3.

Related

jquery datatable with ajax based pagination

I have javascript function that populates datatable using Ajax. My javascript code looks like :
$('#results').dataTable({
// Ajax load data
"ajax": {
"url": "get_intl_tickets",
"type": "POST",
"data": {
"user_id": 451,
"csrfmiddlewaretoken" : csrftoken,
}
}
})
My server side script in django has a function that loads around 500 data rows. Now the problem is that I don't want to load whole data at a time. Instead I want to have first 10 data rows. Then with pagination, another 10 rows like that.
I read the page server side processing documentation of datatables. I tried with "serverSide": true option as well. I am not understanding server side script. There is given an example of PHP. It seems that they are not using any parameters like draw, recordsFiltered, recordsTotal there. There they have used php SSP class. And it is unknown what does it do. I am trying to implement it in django.
But I am not finding proper good documentation to implement. Any help will be appreciated.
Old question but one I also had a surprisingly difficult time finding an answer to, so in case anyone else ends up here... :P
I found this 2020 article very helpful, specifically part 6 showing the "complete code" that includes getting the correct variables, building the SQL query, and how to build/structure the data object that it responds with:
https://makitweb.com/datatables-ajax-pagination-with-search-and-sort-php/
Their example posted below:
<?php
## Database configuration
include 'config.php';
## Read value
$draw = $_POST['draw'];
$row = $_POST['start'];
$rowperpage = $_POST['length']; // Rows display per page
$columnIndex = $_POST['order'][0]['column']; // Column index
$columnName = $_POST['columns'][$columnIndex]['data']; // Column name
$columnSortOrder = $_POST['order'][0]['dir']; // asc or desc
$searchValue = mysqli_real_escape_string($con,$_POST['search']['value']); // Search value
## Search
$searchQuery = " ";
if($searchValue != ''){
$searchQuery = " and (emp_name like '%".$searchValue."%' or
email like '%".$searchValue."%' or
city like'%".$searchValue."%' ) ";
}
## Total number of records without filtering
$sel = mysqli_query($con,"select count(*) as allcount from employee");
$records = mysqli_fetch_assoc($sel);
$totalRecords = $records['allcount'];
## Total number of record with filtering
$sel = mysqli_query($con,"select count(*) as allcount from employee WHERE 1 ".$searchQuery);
$records = mysqli_fetch_assoc($sel);
$totalRecordwithFilter = $records['allcount'];
## Fetch records
$empQuery = "select * from employee WHERE 1 ".$searchQuery." order by ".$columnName." ".$columnSortOrder." limit ".$row.",".$rowperpage;
$empRecords = mysqli_query($con, $empQuery);
$data = array();
while ($row = mysqli_fetch_assoc($empRecords)) {
$data[] = array(
"emp_name"=>$row['emp_name'],
"email"=>$row['email'],
"gender"=>$row['gender'],
"salary"=>$row['salary'],
"city"=>$row['city']
);
}
## Response
$response = array(
"draw" => intval($draw),
"iTotalRecords" => $totalRecords,
"iTotalDisplayRecords" => $totalRecordwithFilter,
"aaData" => $data
);
echo json_encode($response);
Nice exemple:
https://datatables.net/examples/server_side/defer_loading.html
But you need edit server side.
Response demo
{
draw:2,
recordsFiltered:57,
recordsTotal:57
}

How can I assign an order to a certain shop manager in Woocommerce

we have a services woocommerce online shop with three shop managers.
We would like to filter new orders and assign them to one of these three managers. The managers only can see their assigned orders, and can't access or see the rest.
Maybe this could be done by filtering the backend view (admin panel) via custom_field, but I don't know if it is a good approach. Maybe there is a plugin based on role capabilites.
Any suggest?
Thanks.
After having the same issue I combined the solutions of similar, already answered questions and it worked. I know the question is old, but someone may find it helpful. Here is one possible solution:
Add custom meta key containing your desired store_manager id to every order (in my case if a order was from a specific country I wanted only a sprecific store_manager to see it, you can put your custom logic in the before_checkout_create_order() function)
function before_checkout_create_order($order, $data) {
$country = $order->billing_country;
$store_manager_id = '';
$belgium_region = ['BE', 'NL', 'DE'];
$czech_region = ['CZ', 'AT', 'SI', 'HU'];
$uk_region = ['GB'];
if (in_array($country, $belgium_region)) {
// Manually assigning the _store_manager_id using the user id, yours will differ
$store_manager_id = 7;
} else if (in_array($country, $czech_region)) {
$store_manager_id = 3;
} else if (in_array($country, $uk_region)) {
$store_manager_id = 2;
} else {
$store_manager_id = 1;
}
$order->update_meta_data('_store_manager_id', $store_manager_id);
}
add_action('woocommerce_checkout_create_order', 'before_checkout_create_order', 20, 2);
I found the method for assigning custom meta keys to a order ON THIS THREAD you can see what the woocommerce_checkout_create_order and $order->update_meta_data() hook and method do there, it's already greatly explained by its author
Filter the Woocommerce Admin Order list to only show current user assigned orders (but let Master Admin view all orders also)
function custom_admin_shop_manager_orders($query) {
global $pagenow;
$qv = &$query->query_vars;
$currentUserRoles = wp_get_current_user()->roles;
$user_id = get_current_user_id();
if (in_array('shop_manager', $currentUserRoles)) {
if ( $pagenow == 'edit.php' &&
isset($qv['post_type']) && $qv['post_type'] == 'shop_order' ) {
// I use the meta key from step 1 as a second parameter here
$query->set('meta_key', '_store_manager_id');
// The value we want to find is the $user_id defined above
$query->set('meta_value', $user_id);
}
}
return $query;
}
add_filter('pre_get_posts', 'custom_admin_shop_manager_orders');
As you can see we check if the current user role is shop_manager so all the logic after that doesn't count if you're the admin - you will see all the orders, but if you are a shop_manager you will get only your orders. The edit.php is the woocommerce orders list page.
I found the second step in THIS THREAD so you can found more info there also.
Hope this helps you!
This function makes the orders display only to its own authors (shop managers):
function alter_the_edit_screen_query( $wp_query ) {
if ( ( strpos( $_SERVER[ 'REQUEST_URI' ], '/wp-admin/edit.php' ) !== false ) and ( strpos( $_SERVER[ 'REQUEST_URI' ], '/wp-admin/edit.php?post_type=unit' ) === false ) and ( strpos( $_SERVER[ 'REQUEST_URI' ], '/wp-admin/edit.php?post_type=course' ) === false ) ) {
if ( !current_user_can( 'activate_plugins' ) ) {
add_action( 'views_edit-post', 'remove_items_from_edit' );
global $current_user;
$wp_query->set( 'author', $current_user->id );
}
}
}
add_filter('parse_query', 'alter_the_edit_screen_query' );
function remove_items_from_edit( $views ) {
unset($views['all']);
unset($views['publish']);
unset($views['trash']);
unset($views['draft']);
unset($views['pending']);
return $views;
}
This other function hides "All orders" tab to no-admin users (as shop manager):
function my_custom_admin_head() {
if ( ! current_user_can( 'update_core' ) ) {
echo '<style type="text/css">
ul.subsubsub li.all { display:none!important; }
</style>';
}
}
add_action( 'admin_head', 'my_custom_admin_head' );

event dispatch before rendering 404 page of "file not found"

my intention is simple i just want to get my pages in different formats
e.g
www.my-site.com/product-name.html -- will load the page in html
but i want a json object when i type
www.my-site.com/product-name.json
if their is any event that magneto dispatch before rendering 404 page, that can be very helpful
or i have to rewrite app/code/core/Mage/Cms/controllers/indexcontroller.php
more or less
public function defaultNoRouteAction()
{
$this->getResponse()->setHeader('HTTP/1.1','404 Not Found');
$this->getResponse()->setHeader('Status','404 File not found');
$this->loadLayout();
$this->renderLayout();
}
but i don't know how.
I've done something similar, exporting product data when calling an product-url with .xml instead of .html.
I've added an observer listening on product save event, that adds the product-xml URL into core_url_rewrite.
In that event, you have replace .htm(l) with .xml
e.g.
product-name.htm -> catalog/product/view/id/4 -> load product with ID 4 and render product view template, magento core
product-name.xml -> mycustommodule/product/view/id/4 -> load product with ID 4 and render XML, custom module
So you have to add another module called "mycustommodule" that handles the xml output.
Cheers!
i solution that i found is following,it work perfectly but didn't know for sure is it the MAGNETO-WAY
i rewrite Mage_Cms_IndexController noRoute Method,
public function noRouteAction($coreRoute = null) {
// getting current url
$url = Mage::helper('core/url')->getCurrentUrl();
if ( strstr($url,".jsonp") || strstr($url,".json") || strstr($url,".xml") ) {
// geting file-type like json / xml
$format = substr(strrchr($url, "."),1);
// product-handle
$elem = substr( strrchr($url, "/"),1, strpos( strrchr($url, "/") , ".")-1 );
switch ($format) {
case 'json': case 'JSON': case 'jsonp': case 'JSONP':
$this->getResponse()->setHeader('Content-type', 'application/json'); break;
case 'xml': case 'XML':
$this->getResponse()->setHeader('Content-type', 'application/xml'); break;
}
// loding product byproduct-handle
$rewrite = Mage::getModel('core/url_rewrite')->setStoreId(Mage::app()->getStore()->getId())->loadByRequestPath($elem . ".html");
$pid = $rewrite->getProductId();
$cat = Mage::getModel('catalog/category')->setStoreId(Mage::app()->getStore()->getId())->loadByAttribute('url_key', $elem );
if (strpos($url,"hs_review")) { echo Mage::getModel("Hs_Json/review")->wrapper($pid,$format);return;}
if ( $pid ) { echo Mage::getModel("Hs_Json/product")->wrapper($pid,$format);return; }
if ( $cat ) { echo Mage::getModel("Hs_Json/category")->wrapper($cat->getId(),$format);return;}
} else {
$this->getResponse()->setHeader('HTTP/1.1','404 Not Found');
$this->getResponse()->setHeader('Status','404 File not found');
$pageId = Mage::getStoreConfig(Mage_Cms_Helper_Page::XML_PATH_NO_ROUTE_PAGE);
if (!Mage::helper('cms/page')->renderPage($this, $pageId)) {
$this->_forward('defaultNoRoute');
}
}
}
}

Yii2 call 2 functions on change of a dropdown

I have several dropdown imputs and on change of any of them I wanna a value to be offered for a textbox.
I have a code that i placed on each of my dropdown's and it works perfect for me:
<?= $form->field($model4, 'prevoditelj')->dropDownList(ArrayHelper::map(
\app\models\Prevoditelj::find()->orderBy('idprevoditelj')->asArray()->all(),
'idprevoditelj',
'naziv'
),['onchange'=>'
$.get( "'.Url::base().'/index.php?r=zadatak/trosak&id='.$model->projekt.'_"+$("#'.Html::getInputId($model3, 'usluga').'").val()+"_"+$("#'.Html::getInputId($model3, 'dodatak').'").val()+"_"+$("#'.Html::getInputId($model3, 'obr_jedinica').'").val()+"_"+$("#'.Html::getInputId($model4, 'prevoditelj').'").val(), function( data ) {
$( "#'.Html::getInputId($model, 'trosak').'" ).val( data );
});
']) ?>
in a controller I have:
public function actionCijena($id){
$sve=explode("_",$id);//0 - projekt_id, 1 - usluga, 2 - dodatak/jez_kombinacija, 3 - obr_jedinica
$projekt = Projekt::findone($sve[0]);
$klijent = Klijent::findone($projekt['klijent']);
$cjenik_klijent = CjenikKlijent::find()
->asArray()
->where('klijent = :id and usluga = :usluga_id and obr_jedinica = :obr_jedinica and jez_kombinacija = :jez_kombinacija and valuta = :valuta',
['id'=>$klijent['idklijent'],'usluga_id'=>$sve[1],'obr_jedinica'=>$sve[3],'jez_kombinacija'=>$sve[2],'valuta'=>$klijent['valuta']])
->all();
//ako nema, gledaj opci cjenik
if($cjenik_klijent==array()){
$cjenik_klijent = CjenikOpci::find()
->asArray()
->where('usluga = :usluga_id and obr_jedinica = :obr_jedinica and jez_kombinacija = :jez_kombinacija and valuta = :valuta',
['usluga_id'=>$sve[1],'obr_jedinica'=>$sve[3],'jez_kombinacija'=>$sve[2],'valuta'=>$klijent['valuta']])
->all();
}
return $cjenik_klijent[0]['cijena'];
}
The problem I have is that now I wanna add another calculated value to another textbox. but it needs to trigger on the same dropdown's. Unfortunately Get can't return an array so I need to split it up into 2 functions, but how do I call 2 of them?
Ok, I managed to find a solution in returning 2 values in 1 string and then exploding them in jquery. Don't know why I didn't think of that sooner.

gform_field_validation for URL input

I want to change the default validation message for all gravity forms for the URL input only. What is the best way of doing this with gform_field_validation or is there an alternative?
Yes gform_field_validation is the way to do this.
Here's some untested code, but I think it should work. Notice the FORMID and FIELDID that you should update with the appropriate values, not saying the regex will be exactly what you want, I just found it in a quick search here: What is the best regular expression to check if a string is a valid URL?
add_filter( 'gform_field_validation_FORMID_FIELDID', 'custom_url_validation', 10, 4 );
function custom_url_validation( $result, $value, $form, $field ) {
$url_regex = "/^[a-z](?:[-a-z0-9\+\.])*:(?:\/\/(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9\._~\x{A0}-\x{D7FF}\x{F900}-\x{FDCF}\x{FDF0}-\x{FFEF}\x{10000}-\x{1FFFD}\x{20000}-\x{2FFFD}\x{30000}-\x{3FFFD}\x{40000}-\x{4FFFD}\x{50000}-\x{5FFFD}\x{60000}-\x{6FFFD}\x{70000}-\x{7FFFD}\x{80000}-\x{8FFFD}\x{90000}-\x{9FFFD}\x{A0000}-\x{AFFFD}\x{B0000}-\x{BFFFD}\x{C0000}-\x{CFFFD}\x{D0000}-\x{DFFFD}\x{E1000}-\x{EFFFD}!\$&'\(\)\*\+,;=:])*#)?(?:\[(?:(?:(?:[0-9a-f]{1,4}:){6}(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:\.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3})|::(?:[0-9a-f]{1,4}:){5}(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:\.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3})|(?:[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){4}(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:\.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3})|(?:[0-9a-f]{1,4}:[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){3}(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:\.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3})|(?:(?:[0-9a-f]{1,4}:){0,2}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){2}(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:\.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3})|(?:(?:[0-9a-f]{1,4}:){0,3}[0-9a-f]{1,4})?::[0-9a-f]{1,4}:(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:\.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3})|(?:(?:[0-9a-f]{1,4}:){0,4}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:\.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3})|(?:(?:[0-9a-f]{1,4}:){0,5}[0-9a-f]{1,4})?::[0-9a-f]{1,4}|(?:(?:[0-9a-f]{1,4}:){0,6}[0-9a-f]{1,4})?::)|v[0-9a-f]+[-a-z0-9\._~!\$&'\(\)\*\+,;=:]+)\]|(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(?:\.(?:[0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}|(?:%[0-9a-f][0-9a-f]|[-a-z0-9\._~\x{A0}-\x{D7FF}\x{F900}-\x{FDCF}\x{FDF0}-\x{FFEF}\x{10000}-\x{1FFFD}\x{20000}-\x{2FFFD}\x{30000}-\x{3FFFD}\x{40000}-\x{4FFFD}\x{50000}-\x{5FFFD}\x{60000}-\x{6FFFD}\x{70000}-\x{7FFFD}\x{80000}-\x{8FFFD}\x{90000}-\x{9FFFD}\x{A0000}-\x{AFFFD}\x{B0000}-\x{BFFFD}\x{C0000}-\x{CFFFD}\x{D0000}-\x{DFFFD}\x{E1000}-\x{EFFFD}!\$&'\(\)\*\+,;=#])*)(?::[0-9]*)?(?:\/(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9\._~\x{A0}-\x{D7FF}\x{F900}-\x{FDCF}\x{FDF0}-\x{FFEF}\x{10000}-\x{1FFFD}\x{20000}-\x{2FFFD}\x{30000}-\x{3FFFD}\x{40000}-\x{4FFFD}\x{50000}-\x{5FFFD}\x{60000}-\x{6FFFD}\x{70000}-\x{7FFFD}\x{80000}-\x{8FFFD}\x{90000}-\x{9FFFD}\x{A0000}-\x{AFFFD}\x{B0000}-\x{BFFFD}\x{C0000}-\x{CFFFD}\x{D0000}-\x{DFFFD}\x{E1000}-\x{EFFFD}!\$&'\(\)\*\+,;=:#]))*)*|\/(?:(?:(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9\._~\x{A0}-\x{D7FF}\x{F900}-\x{FDCF}\x{FDF0}-\x{FFEF}\x{10000}-\x{1FFFD}\x{20000}-\x{2FFFD}\x{30000}-\x{3FFFD}\x{40000}-\x{4FFFD}\x{50000}-\x{5FFFD}\x{60000}-\x{6FFFD}\x{70000}-\x{7FFFD}\x{80000}-\x{8FFFD}\x{90000}-\x{9FFFD}\x{A0000}-\x{AFFFD}\x{B0000}-\x{BFFFD}\x{C0000}-\x{CFFFD}\x{D0000}-\x{DFFFD}\x{E1000}-\x{EFFFD}!\$&'\(\)\*\+,;=:#]))+)(?:\/(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9\._~\x{A0}-\x{D7FF}\x{F900}-\x{FDCF}\x{FDF0}-\x{FFEF}\x{10000}-\x{1FFFD}\x{20000}-\x{2FFFD}\x{30000}-\x{3FFFD}\x{40000}-\x{4FFFD}\x{50000}-\x{5FFFD}\x{60000}-\x{6FFFD}\x{70000}-\x{7FFFD}\x{80000}-\x{8FFFD}\x{90000}-\x{9FFFD}\x{A0000}-\x{AFFFD}\x{B0000}-\x{BFFFD}\x{C0000}-\x{CFFFD}\x{D0000}-\x{DFFFD}\x{E1000}-\x{EFFFD}!\$&'\(\)\*\+,;=:#]))*)*)?|(?:(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9\._~\x{A0}-\x{D7FF}\x{F900}-\x{FDCF}\x{FDF0}-\x{FFEF}\x{10000}-\x{1FFFD}\x{20000}-\x{2FFFD}\x{30000}-\x{3FFFD}\x{40000}-\x{4FFFD}\x{50000}-\x{5FFFD}\x{60000}-\x{6FFFD}\x{70000}-\x{7FFFD}\x{80000}-\x{8FFFD}\x{90000}-\x{9FFFD}\x{A0000}-\x{AFFFD}\x{B0000}-\x{BFFFD}\x{C0000}-\x{CFFFD}\x{D0000}-\x{DFFFD}\x{E1000}-\x{EFFFD}!\$&'\(\)\*\+,;=:#]))+)(?:\/(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9\._~\x{A0}-\x{D7FF}\x{F900}-\x{FDCF}\x{FDF0}-\x{FFEF}\x{10000}-\x{1FFFD}\x{20000}-\x{2FFFD}\x{30000}-\x{3FFFD}\x{40000}-\x{4FFFD}\x{50000}-\x{5FFFD}\x{60000}-\x{6FFFD}\x{70000}-\x{7FFFD}\x{80000}-\x{8FFFD}\x{90000}-\x{9FFFD}\x{A0000}-\x{AFFFD}\x{B0000}-\x{BFFFD}\x{C0000}-\x{CFFFD}\x{D0000}-\x{DFFFD}\x{E1000}-\x{EFFFD}!\$&'\(\)\*\+,;=:#]))*)*|(?!(?:%[0-9a-f][0-9a-f]|[-a-z0-9\._~\x{A0}-\x{D7FF}\x{F900}-\x{FDCF}\x{FDF0}-\x{FFEF}\x{10000}-\x{1FFFD}\x{20000}-\x{2FFFD}\x{30000}-\x{3FFFD}\x{40000}-\x{4FFFD}\x{50000}-\x{5FFFD}\x{60000}-\x{6FFFD}\x{70000}-\x{7FFFD}\x{80000}-\x{8FFFD}\x{90000}-\x{9FFFD}\x{A0000}-\x{AFFFD}\x{B0000}-\x{BFFFD}\x{C0000}-\x{CFFFD}\x{D0000}-\x{DFFFD}\x{E1000}-\x{EFFFD}!\$&'\(\)\*\+,;=:#])))(?:\?(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9\._~\x{A0}-\x{D7FF}\x{F900}-\x{FDCF}\x{FDF0}-\x{FFEF}\x{10000}-\x{1FFFD}\x{20000}-\x{2FFFD}\x{30000}-\x{3FFFD}\x{40000}-\x{4FFFD}\x{50000}-\x{5FFFD}\x{60000}-\x{6FFFD}\x{70000}-\x{7FFFD}\x{80000}-\x{8FFFD}\x{90000}-\x{9FFFD}\x{A0000}-\x{AFFFD}\x{B0000}-\x{BFFFD}\x{C0000}-\x{CFFFD}\x{D0000}-\x{DFFFD}\x{E1000}-\x{EFFFD}!\$&'\(\)\*\+,;=:#])|[\x{E000}-\x{F8FF}\x{F0000}-\x{FFFFD}|\x{100000}-\x{10FFFD}\/\?])*)?(?:\#(?:(?:%[0-9a-f][0-9a-f]|[-a-z0-9\._~\x{A0}-\x{D7FF}\x{F900}-\x{FDCF}\x{FDF0}-\x{FFEF}\x{10000}-\x{1FFFD}\x{20000}-\x{2FFFD}\x{30000}-\x{3FFFD}\x{40000}-\x{4FFFD}\x{50000}-\x{5FFFD}\x{60000}-\x{6FFFD}\x{70000}-\x{7FFFD}\x{80000}-\x{8FFFD}\x{90000}-\x{9FFFD}\x{A0000}-\x{AFFFD}\x{B0000}-\x{BFFFD}\x{C0000}-\x{CFFFD}\x{D0000}-\x{DFFFD}\x{E1000}-\x{EFFFD}!\$&'\(\)\*\+,;=:#])|[\/\?])*)?$/i";
if ( !preg_match( $url_regex, $value) ) {
$result['is_valid'] = false;
$result['message'] = 'Please enter a valid url!';
}
return $result;
}

Resources