How to prevent users from registering using diffrent characters than arabic with regex ?) - preg-match

I want to prevent my visitors who want to become users in my websites from using Latin characters.
I want them to use only Arabic user names.
How to do that with regex and preg_match?

I think this has been answered here -> stackoverflow.com - How do I detect if an input string is Arabic
<?
function uniord($u) {
// i just copied this function fron the php.net comments, but it should work fine!
$k = mb_convert_encoding($u, 'UCS-2LE', 'UTF-8');
$k1 = ord(substr($k, 0, 1));
$k2 = ord(substr($k, 1, 1));
return $k2 * 256 + $k1;
}
function is_arabic($str) {
if(mb_detect_encoding($str) !== 'UTF-8') {
$str = mb_convert_encoding($str,mb_detect_encoding($str),'UTF-8');
}
/*
$str = str_split($str); <- this function is not mb safe, it splits by bytes, not characters. we cannot use it
$str = preg_split('//u',$str); <- this function woulrd probably work fine but there was a bug reported in some php version so it pslits by bytes and not chars as well
*/
preg_match_all('/.|\n/u', $str, $matches);
$chars = $matches[0];
$arabic_count = 0;
$latin_count = 0;
$total_count = 0;
foreach($chars as $char) {
//$pos = ord($char); we cant use that, its not binary safe
$pos = uniord($char);
echo $char ." --> ".$pos.PHP_EOL;
if($pos >= 1536 && $pos <= 1791) {
$arabic_count++;
} else if($pos > 123 && $pos < 123) {
$latin_count++;
}
$total_count++;
}
if(($arabic_count/$total_count) > 0.6) {
// 60% arabic chars, its probably arabic
return true;
}
return false;
}
$arabic = is_arabic('عربية إخبارية تعمل على مدار اليوم. يمكنك مشاهدة بث القناة من خلال الموقع');
var_dump($arabic);
?>

They also show a preg_match statement
$str = "بسم الله";
if (preg_match('/[أ-ي]/ui', $str)) {
echo "A match was found.";
} else {
echo "A match was not found.";
}

You could use the unicode property \p{Arabic}, see http://perldoc.perl.org/perluniprops.html
Using php:
preg_match('/^\p{Arabic}+$/u', $string, $matches);

Related

How to use preg_replace_callback

I am trying to replace the 2nd occurrence of the $target_str.
If someone could explain how preg_replace_callback works I would appreciate it.
I don't understand the function($match) part. How do I set it so it matches the 2nd occurrence and only replaces that string?
I have the code (but it doesn't work as I want it to).
$replacement_params['target_str'] = "[\n]";
$replacement_params['replacement_str'] = "\n<ads media=googleAds1 />\n";
$target_str = $this->params['target_str'];
$replacement_str = $this->params['replacement_str'];
$num_matches;
$i = 0;
$new_text = preg_replace_callback("/".$target_str."/U",
function ( $match ) {
if ( $i === 1 ) {
return $replacement_str;
} else {
return $match[0];
}
$i++;
} , $article_text, 1, $num_matches );
Updated
Using built-in counter variable of preg_replace_callback:
$new_text = preg_replace_callback("/$target_str/U",
function($matches) use (&$count, $replacement_str)
{
$count++;
return ($count == 2) ? $replacement_str : $matches[0];
} , $article_text, -1, $count);

Why trie is also called "prefix tree"?

I was reading this article on Wikipedia and stumbled on the line which says "trie is also called prefix tree".
I know the usage of trie but why is it called "prefix tree"?
As they can be searched by prefixes. You can also reverse the trie and find wildcards: http://phpir.com/tries-and-wildcards.
For example the term academic would be c-i-m-e-d-a-c-a. Using the same
technique as before we can now search for all words that end with a
certain phrase, allowing us to handle wildcards at the beginning of
query terms, e.g. *cademically.
<?php
function buildTries($words) {
$trie = new Trie();
$rtrie = new Trie();
foreach($words as $word) {
$trie->add($word);
$rtrie->add(strrev($word));
}
return array('trie' => $trie, 'rtrie' => $rtrie);
}
function searchTries($search, $tries) {
$terms = explode('*', $search);
if(count($terms) > 2) {
return false;
}
if(strlen($terms[0]) && strlen($terms[0])) {
// middle wildcard
$straight = $tries['trie']->prefixSearch($terms[0]);
$rev = $tries['rtrie']->prefixSearch(strrev($terms[1]));
return array_intersect($straight, reverseArray($rev));
} else if(strlen($terms[1]) ) {
// leading wildcard
return reverseArray($tries['rtrie']->prefixSearch(strrev($terms[1])));
} else {
// trailing wildcard
return $tries['trie']->prefixSearch($terms[0]);
}
}
function reverseArray($keys) {
$return = array();
foreach($keys as $key => $value) {
$return[strrev($key)] = $value;
}
return $return;
}
/* Do some searches */
$words = array(
'adder',
'addled',
'abject',
'agreement',
'astronaut',
'handily',
'happily',
'helpfully'
);
$tries = buildTries($words);
$return = searchTries('h*ly', $tries);
var_dump($return);
$return = searchTries('ha*ly', $tries);
var_dump($return);
?>
The results from the two var dumps look like this:
array(3) {
["handily"]=>
NULL
["happily"]=>
NULL
["helpfully"]=>
NULL
}
array(2) {
["handily"]=>
NULL
["happily"]=>
NULL
}

Turkish character convert in php

When I add a retailer with Turkish character, those Turkish characters are omitted in the URL.
The funciton is;
function friendlyURL($string, $down = 0)
{
$string = preg_replace("`\[.*\]`U","",$string);
$string = preg_replace('`&(amp;)?#?[a-z0-9]+;`i','-',$string);
$string = htmlentities($string, ENT_COMPAT, 'utf-8');
$string = preg_replace( "`&([a-z])(acute|uml|circ|grave|ring|cedil|slash|tilde|caron|lig|quot|rsquo);`i","\\1", $string );
$string = preg_replace( array("`[^a-z0-9]`i","`[-]+`") , "-", $string);
if ($down == 1)
{
$string = str_replace('-','_',$string);
return strtolower(trim($string, '_'));
}
else
{
return strtolower(trim($string, '-'));
}
}
The url for the retailer named "deneme mağazası" is as "domain.com/deneme-ma-azas-site"
How the Turkish characters can be converted?
according to RFC 1738 this is not possible.
here is a reference regarding that
http://www.blooberry.com/indexdot/html/topics/urlencoding.htm

How to validate time input in Codeigniter

I have a text box in a form to enter time and I use to check the validation using jquery. But now I want to check the validation of the text box using the codeigniter's built-in validation system. Would you please kindly tell me how to validate time input using codeigniter's built-in validation system?
Here's the code how I use to do it using jquery:
<script type="text/javascript">
$().ready(function() {
$.validator.addMethod("time", function(value, element) {
return this.optional(element) || /^(([0-1]?[0-2])|([2][0-3])):([0-5]?[0-9])\s(a|p)m?$/i.test(value);
}, "Enter Valid Time");
$("#theForm").validate({
rules: {
time: "required time",
},
});
});
</script>
And here is the html
<input class="time" type="text" name="time1" size="15">
Something like this perhaps
// Validation rule in controller
$this->form_validation->set_rules('time', 'time', 'trim|min_length[3]|max_length[5]|callback_validate_time');
and a callback:
public function validate_time($str)
{
//Assume $str SHOULD be entered as HH:MM
list($hh, $mm) = split('[:]', $str);
if (!is_numeric($hh) || !is_numeric($mm))
{
$this->form_validation->set_message('validate_time', 'Not numeric');
return FALSE;
}
else if ((int) $hh > 24 || (int) $mm > 59)
{
$this->form_validation->set_message('validate_time', 'Invalid time');
return FALSE;
}
else if (mktime((int) $hh, (int) $mm) === FALSE)
{
$this->form_validation->set_message('validate_time', 'Invalid time');
return FALSE;
}
return TRUE;
}
Modifying what #danneth posted, in order to accept time as HH:MM:SS
public function validate_time($str){
if (strrchr($str,":")) {
list($hh, $mm, $ss) = explode(':', $str);
if (!is_numeric($hh) || !is_numeric($mm) || !is_numeric($ss)){
return FALSE;
}elseif ((int) $hh > 24 || (int) $mm > 59 || (int) $ss > 59){
return FALSE;
}elseif (mktime((int) $hh, (int) $mm, (int) $ss) === FALSE){
return FALSE;
}
return TRUE;
}else{
return FALSE;
}
}
*Changed deprecated split for explode
*Added one more condition in case the parameter received is a string like 'aaaaa'
*Changed form validation min_length from 3 to 8 (so you make sure the 8 characters from HH:MM:SS are entered):
$this->form_validation->set_rules('time','Time','required|trim|min_length[8]|max_length[8]|callback_validate_time');
have improvised #danneth 's code hope it helps
function _validate_date($str_date)
{
if($str_date!='')
{
/*
Remove Whitespaces if any
*/
$str_date = trim($str_date);
list($hh,$sub) = split('[:]', $str_date);
/*
Separate Minute from Meridian
e.g 50 PM ===> $mm=60 and $md=PM
*/
$mm = substr($sub, 0,2);
$md = trim(substr($sub, 2,strlen($sub)));
/*
Make Meridian uppercase
Implicitly Check if Meridian is PM or AM
if not then make it PM
*/
$md = strtoupper($md);
if(!in_array($md, array('PM',"AM")))
{
return FALSE;
}
/*
Check if MM and HH are numeric
*/
if(!is_numeric($hh) || !is_numeric($mm))
{
$this->form_validation->set_message('Invalid Time','Illegal chars found');
return 11;
}
$hh = (int)$hh;
$mm = (int)$mm;
/*
Check HH validity should not be less than 0 and more 24
*/
if($hh<0 || $hh>24)
{
return FALSE;
}
/*
Check MM validity should not be less than 0 and more than 59
*/
if($mm<0 | $mm>59)
{
return FALSE;
}
/*
Parse HH and MM to int for further operation and check it generates validate time
*/
if(mktime($hh,$mm)==FALSE)
{
$this->form_validation->set_message('Invalid Time','Check Time');
return FALSE;
}
return TRUE;
}
else
{
return FALSE;
}
}

get byte value from shorthand byte notation in php.ini

Is there any way to get the byte values from the strings returned from functions like ini_get('upload_max_filesize') and ini_get('post_max_size') when they are using shorthand byte notation? For example get 4194304 from 4M ? I could hack together a function that does this but I would be surprised if there wasn't some built in way of doing this.
The paragraph you linked to ends:
You may not use these shorthand notations outside of php.ini, instead
use an integer value of bytes. See the ini_get() documentation for an
example on how to convert these values.
This leads you to something like this (which I have slightly modified):
function return_bytes($val)
{
$val = trim($val);
if (is_numeric($val))
return $val;
$last = strtolower($val[strlen($val)-1]);
$val = substr($val, 0, -1); // necessary since PHP 7.1; otherwise optional
switch($last) {
// The 'G' modifier is available since PHP 5.1.0
case 'g':
$val *= 1024;
case 'm':
$val *= 1024;
case 'k':
$val *= 1024;
}
return $val;
}
Use it like so:
echo return_bytes("3M");
// Output: 3145728
There is no built-in function to perform this task; recall that, really, INI settings are designed for use internally within PHP. The PHP source uses a similar function to the above.
Gah! Just found the answer on http://www.php.net/manual/en/function.ini-get.php
Just needed to RTM...
function return_bytes($val) {
$val = trim($val);
$last = strtolower($val[strlen($val)-1]);
switch($last) {
// The 'G' modifier is available since PHP 5.1.0
case 'g':
$val *= 1024;
case 'm':
$val *= 1024;
case 'k':
$val *= 1024;
}
return $val;
}
This is my suggestion which should be future-proof (with regard to PHP Versions 7++)!
function return_bytes($val, $gotISO = false) {
// This is my ultimate "return_bytes" function!
// Converts (not only) the PHP shorthand notation which is returned by e.g. "ini_get()"
// Special features:
// Doesn't need regular expression and switch-case conditionals.
// Identifies beside "Kilo", "Mega" and "Giga" also "Tera", "Peta", "Exa", "Zetta", and "Yotta" too!
// Ignores spaces and doesn't make no difference between e.g. "M" or "MB"!
// By default possible commas (,) as thousand separator will be erased. Example: "1,000.00" will "be 1000.00".
// If ($gotISO == true) it converts ISO formatted values like "1.000,00" into "1000.00".
$pwr = 0;
if(empty($val)) return 0;
$val = trim($val);
if (is_numeric($val)) return $val;
if ($gotISO) {
$val = str_replace('.','',$val); // wipe possibe thousend separators (.)
$val = str_replace(',','.',$val); // convert ISO comma to value point
} else {
$val = str_replace(',','',$val); // wipe possibe thousend separators (,)
}
$val = str_replace(' ','',$val);
if (floatval($val) == 0) return 0;
if (stripos($val, 'k') !== false) $pwr = 1;
elseif (stripos($val, 'm') !== false) $pwr = 2;
elseif (stripos($val, 'g') !== false) $pwr = 3;
elseif (stripos($val, 't') !== false) $pwr = 4;
elseif (stripos($val, 'p') !== false) $pwr = 5;
elseif (stripos($val, 'e') !== false) $pwr = 6;
elseif (stripos($val, 'z') !== false) $pwr = 7;
elseif (stripos($val, 'y') !== false) $pwr = 8;
$val *= pow(1024, $pwr);
return $val;
}
... have fun with it!
I found a lot of solution to solve this problem and there should have been a builtin function to solve this. In any case two things to highlight about this problem:
This is very specific to PHP's shorthand byte values as explained here: http://php.net/manual/en/faq.using.php#faq.using.shorthandbytes and should only be used in this context.
Most modern IDEs will give warning for switch statements without break.
Here is a solution that covers everything:
/**
* Convert PHP's directive values to bytes (including the shorthand syntax).
*
* #param string $directive The PHP directive from which to get the value from.
*
* #return false|int Returns the value of the directive in bytes if available, otherwise false.
*/
function php_directive_value_to_bytes($directive) {
$value = ini_get($directive);
// Value must be a string.
if (!is_string($value)) {
return false;
}
preg_match('/^(?<value>\d+)(?<option>[K|M|G]*)$/i', $value, $matches);
$value = (int) $matches['value'];
$option = strtoupper($matches['option']);
if ($option) {
if ($option === 'K') {
$value *= 1024;
} elseif ($option === 'M') {
$value *= 1024 * 1024;
} elseif ($option === 'G') {
$value *= 1024 * 1024 * 1024;
}
}
return $value;
}
Neither one of the Version shown above will work with PHP 7.2x anymore, as I found out.By use of this,with PHP 7.0 + 7.1, it works, but not with PHP 7.x
Ernie
private function return_bytes ($val) {
if(empty($val))return 0;
$val = trim($val);
preg_match('#([0-9]+)[\s]*([a-z]+)#i', $val, $matches);
$last = '';
if(isset($matches[2])){
$last = $matches[2];
}
if(isset($matches[1])){
$val = (int) $matches[1];
}
switch (strtolower($last)){
case 'g':
case 'gb':
$val *= 1024;
case 'm':
case 'mb':
$val *= 1024;
case 'k':
case 'kb':
$val *= 1024;
}
return (int) $val;
}
Here is one way.
$str=ini_get('upload_max_filesize');
preg_match('/[0-9]+/', $str, $match);
echo ($match[0] * 1024 * 1024); // <--This is MB converted to bytes

Resources