Customizing user_nicename in wp_users table in wordpress - mysql

By default wordpress will santitize the contents written to user_nicename column in wp_users table. It will remove spaces, some special characters and change uppercase to lowercase. Will it be possible to update user_nicename column without sanitizations?

It is possible using the pre_user_nicename filter. You can read on it here https://developer.wordpress.org/reference/hooks/pre_user_nicename/ The filter is applied right after the nicename is sanitized, but we can still access the unsanitized data. This is from wp-includes/user.php
/*
* If a nicename is provided, remove unsafe user characters before using it.
* Otherwise build a nicename from the user_login.
*/
if ( ! empty( $userdata['user_nicename'] ) ) {
$user_nicename = sanitize_user( $userdata['user_nicename'], true );
if ( mb_strlen( $user_nicename ) > 50 ) {
return new WP_Error( 'user_nicename_too_long', __( 'Nicename may not be longer than 50 characters.' ) );
}
} else {
$user_nicename = mb_substr( $user_login, 0, 50 );
}
$user_nicename = sanitize_title( $user_nicename );
// Store values to save in user meta.
$meta = array();
/**
* Filters a user's nicename before the user is created or updated.
*
* #since 2.0.3
*
* #param string $user_nicename The user's nicename.
*/
$user_nicename = apply_filters( 'pre_user_nicename', $user_nicename );
$raw_user_url = empty( $userdata['user_url'] ) ? '' : $userdata['user_url'];
You can still access the unmodified nicename entered by the user with the $userdata['user_nicename'] variable. So an example filter would go like this:
add_filter( 'pre_user_nicename', 'my_nicename_modification');
function my_nicename_modification($userdata) {
/*do anything you want with $userdata['user_nicename'] here
or leave blank if you want it saved just as the user typed it in */
return $userdata['user_nicename'];
}
This will stop $user_nicename = sanitize_title( $user_nicename ); from running, on which you can read more on here https://codex.wordpress.org/Function_Reference/sanitize_title. That is that modifies the nicename as you explained in your question. Hope this helps

Related

How to change the search action in wordpress search bar?

Create a new post and publish it.
The title is my test for search, content in it is as below:
no host route
Check what happen in wordpress database.
select post_title from wp_posts
where post_content like "%no%"
and post_content like "%route%"
and post_content like "%to%"
and post_content like "%host%";
The post named my test for search will not be in the select's result.
Type no route to host in wordpress search bar,and click enter.
The post named my test for search shown as result.
I found the reason that the webpage contain to ,in the left upper side corner ,there is a word Customize which contains the searched word to.
How to change such search action in wordpress serach bar?
I want to make the search behavior in wordpress saerch bar, for example ,when you type no route to host, equal to the following sql command.
select post_title from wp_posts where post_content like "%no%route%to%host%";
All the plugins in my wordpress.
CodePen Embedded Pens Shortcode
Crayon Syntax Highlighter
Disable Google Fonts
Quotmarks Replacer
SyntaxHighlighter Evolved
There's this addition to the SQL WHERE clause on wp-includes/class-wp-query.php:1306:
<?php
// wp-includes/class-wp-query.php:~1306
foreach ( $q['search_terms'] as $term ) {
//...
$like = $n . $wpdb->esc_like( $term ) . $n;
$search .= $wpdb->prepare( "{$searchand}(({$wpdb->posts}.post_title $like_op %s) $andor_op ({$wpdb->posts}.post_excerpt $like_op %s) $andor_op ({$wpdb->posts}.post_content $like_op %s))", $like, $like, $like );
// ...
Therefore, I'd hook into the pre_get_posts, and supply the words of the query as explicit "search_terms", since they get added into that clause, with the LIKE modifier just as you said were looking for!
So, we might do something like this:
<?php
// functions.php
function fuzzify_query(\WP_Query $q) {
if (true === $q->is_search()
&& true === property_exists($q, 'query')
&& true === key_exists('s', $q->query)
) {
$original_query = $q->query['s'];
$words = explode(' ', $original_query);
$fuzzy_words = array_map(
function($word) {
return '%'.$word.'%';
},
$words
);
$q->query_vars['search_terms'] = $fuzzy_words;
return $q;
}
return $q;
}
add_action('pre_get_posts', 'fuzzify_query', 100); // Or whatever priority your fuzziness requires!

Adding user ip to existing meta_value with single meta_id as array

I am currently getting the user IP on a slider change and sending it to the WP DB but I want to keep the DB smaller and have a single meta_id for the list of IPs.
My current code is sort of working but as it adds the new ip to the existing array something is causing it to turn into a multidimensional one and breaking it.
Here is my code.
$user_ip = $_POST['ip'];
$user_score = $_POST['sliderValue'];
$postID = $_POST['post_id'];
$currentIPs = maybe_unserialize(get_post_meta( $postID, 'user_ip'));
$currentIPs[] = $user_ip;
if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
update_post_meta($postID, 'user_ip', $currentIPs);
echo var_dump($currentIPs);
}
die();
}
I have tried with add_post_meta and that works fine but it creates a new meta_id for each IP which would just make the database huge. For performance and space saving I was just one key and ID with all the values.
The function is programmed to create a new meta_id every time you use update_meta_data.
However the workaround is that you can store the IPS within same meta_id by seperating IPS with commas.
Replace
$currentIPs = maybe_unserialize(get_post_meta( $postID, 'user_ip'));
$currentIPs[] = $user_ip;
if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
update_post_meta($postID, 'user_ip', $currentIPs);
With
$currentIPs = $user_ip;
$userIp = get_post_meta($postID, 'user_ip',true);
if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
if (empty($userIp)) {
update_post_meta($postID, 'user_ip', $currentIPs);
} else {
$newvalue = $currentIPs .','. $userIp;
update_post_meta($postID, 'user_ip', $newvalue);
}
Later if you want these data in an array, you can use php's explode() function afterwards

Query two combined fields with one value

I have a table name 'user' for example. I have field 'name' and field 'family' in this table.
I use jQueryUI auto-complete for top search in my site for search people just like Facebook.
Example of jQueryUI I use (half code):
$( "#mainsearch" ).bind( "keydown", function( event ) {
if ( event.keyCode === $.ui.keyCode.TAB &&
$( this ).data( "ui-autocomplete" ).menu.active ) {
event.preventDefault();
}
})
And I have PHP files get search result code like this:
$name = $_GET['term'];
$results = array();
$s = qselectall("select * from user where(name LIKE '%$name%' or family LIKE '%$name%' ) limit 15",$db);
while($f = mysqli_fetch_array($s,MYSQLI_ASSOC)){
if($userid != $f['id']){
$name = $f['name'].' '.$f['family'];
$url = $siteurl.$f['username'].'/';
array_push($results, array('id' => $f['id'],'value' => $name,'url' => $url));
}
}
echo json_encode($results);
But it has 1 problem.
User's cannot search with name and family.
They must insert name OR family just in input box for it to work.
Is there any SQL code for search LIKE where( name and family = $text) ?
EXAMPLE:
We have someone with name 'alex' and with last name 'alexian'.
So user search for 'alex alexian' but they get no results why?
Because not name and not family in table = 'alex alexian'.
So they must search 'alex' or 'alexian' for it to work.
Try this:
SELECT * FROM user
WHERE concat_ws(' ',name,family)
LIKE '%$name%';
The concat_ws function concatenates multiple columns 'with separator' (_ws). In this case, the separator is a space (' '). See the MySQL documentation for further information.
Demo: http://www.sqlfiddle.com/#!2/aac0f/8

Saving text box input to XML or txt file in HTML

I'm working on a HTML page project where I have 2 text boxes and basically I want to save the input data that the user put in the text boxes. What we did in my C# class was that we saved all input into a XML file so I'm assuming there is a similar way? Either to a XML or some other file that can store text?
Anyone that knows a solution?
I recommend the following php script
<?php
// check that form was submitted
// (you'll need to change these indices to match your form field names)
if( !empty( $_POST['firstname'] ) && !empty( $_POST['lastname'] ) ){
// remove html tags from submission
// (since you don't want them)
$firstname = strip_tags( $_POST['firstname'] );
$lastname = strip_tags( $_POST['lastname'] );
// create the date
// (you can change the format as desired)
$date = date( 'Y-m-d' );
// create an array that holds your info
$record = array( $firstname,$lastname,$date );
// save the record to your .txt file (I still recommend JSON)
$json = json_encode( $record );
$file = '/_server_/path/to/yourfile.txt';
file_put_contents( $json,$file );
}

Using json API pull to store in file or database

I am trying to pull data from the justin.tv API and store the echo I get in the below code in to a database or a file to be included in the sidebar of website. I am not sure on how to do this. The example of what I am trying to achieve is the live streamers list on the sidebar of teamliquid.net. Which I have done but doing it the way I have done it slows the site way down because it does about 50 json requests every time the page loads. I just need to get this in to a cached file that updates every 60 seconds or so. Any ideas?
<?php
$json_file = file_get_contents("http://api.justin.tv/api/stream/list.json?channel=colcatz");
$json_array = json_decode($json_file, true);
if ($json_array[0]['name'] == 'live_user_colcatz') echo 'coL.CatZ Live<br>';
$json_file = file_get_contents("http://api.justin.tv/api/stream/list.json?channel=coldrewbie");
$json_array = json_decode($json_file, true);
if ($json_array[0]['name'] == 'live_user_coldrewbie') echo 'coL.drewbie Live<br>';
?>
I'm not entirely sure how you would imagine this being cached, but the code below is an adaption of a block of code I've used in the past for some Twitter work. There are a few things that could probably be done better from a security perspective. Anyway, this gives you a generic way of grabbing the Feed, parsing through it, and then sending it to the database.
Warning: This assumes that there is a database connection already established within your own system.
(* Make sure you scroll to the bottom of the code window *)
/**
* Class SM
*
* Define a generic wrapper class with some system
* wide functionality. In this case we'll give it
* the ability to fetch a social media feed from
* another server for parsing and possibly caching.
*
*/
class SM {
private $api, $init, $url;
public function fetch_page_contents ($url) {
$init = curl_init();
try {
curl_setopt($init, CURLOPT_URL, $url);
curl_setopt($init, CURLOPT_HEADER, 0);
curl_setopt($init, CURLOPT_RETURNTRANSFER, 1);
} catch (Exception $e) {
error_log($e->getMessage());
}
$output = curl_exec($init);
curl_close($init);
return $output;
}
}
/**
* Class JustinTV
*
* Define a specific site wrapper for getting the
* timeline for a specific user from the JustinTV
* website. Optionally you can return the code as
* a JSON string or as a decoded PHP array with the
* $api_decode argument in the get_timeline function.
*
*/
class JustinTV extends SM {
private $timeline_document,
$api_user,
$api_format,
$api_url;
public function get_timeline ($api_user, $api_decode = 1, $api_format = 'json', $api_url = 'http://api.justin.tv/api/stream/list') {
$timeline_document = $api_url . '.' . $api_format . '?channel=' . $api_user;
$SM_init = new SM();
$decoded_json = json_decode($SM_init->fetch_page_contents($timeline_document));
// Make sure that our JSON is really JSON
if ($decoded_json === null && json_last_error() !== JSON_ERROR_NONE) {
error_log('Badly formed, dangerous, or altered JSON string detected. Exiting program.');
}
if ($api_decode == 1) {
return $decoded_json;
}
return $SM_init->fetch_page_contents($timeline_document);
}
}
/**
* Instantiation of the class
*
* Instantiate our JustinTV class, fetch a user timeline
* from JustinTV for the user colcatz. The loop through
* the results and enter each of the individual results
* into a database table called cache_sm_justintv.
*
*/
$SM_JustinTV = new JustinTV();
$user_timeline = $SM_JustinTV->get_timeline('colcatz');
foreach ($user_timeline AS $entry) {
// Here you could check whether the entry already exists in the system before you cache it, thus reducing duplicate ID's
$date = date('U');
$query = sprintf("INSERT INTO `cache_sm_justintv` (`id`, `cache_content`, `date`) VALUES (%d, '%s', )", $entry->id, $entry, $date);
$result = mysql_query($query);
// Do some other stuff and then close the MySQL Connection when your done
}