Getting error on react native "json parse error unexpected eof" - wordpress

I have followed this code from the site "http://carlofontanos.com/user-login-with-wordpress-using-react-native/"
I have done my Login.js like this
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
TextInput,
TouchableOpacity,
Keyboard
} from 'react-native';
import { AsyncStorage } from 'react-native';
import {Actions} from 'react-native-router-flux';
import { StackNavigator } from 'react-navigation';
export default class LoginForm extends Component<{}> {
constructor(props){
super(props)
this.state={
userEmail:'',
userPassword:'',
validating: false
}
}
login = () =>{
this.state.validating = true;
const {userEmail,userPassword} = this.state;
let reg = /^\w+([\.-]?\w+)*#\w+([\.-]?\w+)*(\.\w{2,3})+$/ ;
if(userEmail==""){
//alert("Please enter Email address");
this.setState({email:'Please enter Email address'})
}
else if(reg.test(userEmail) === false)
{
//alert("Email is Not Correct");
this.setState({email:'Email is Not Correct'})
return false;
}
else if(userPassword==""){
this.setState({email:'Please enter password'})
}
else{
fetch('http://siteURL/wetest/userlogin.php',{
method:'post',
header:{
'Accept': 'application/json',
'Content-type': 'application/json'
},
body:JSON.stringify({
email: userEmail,
password: userPassword
})
})
.then((response) => response.json())
.then((responseJson)=>{
let data = responseJson.data;
if (this.saveToStorage(data)){
this.setState({
validating: false
});
alert("Successfully Login");
/* Redirect to home page */
Actions.home()
} else {
alert("Wrong Login Details");
}
})
.catch((error)=>{
console.error(error);
});
}
Keyboard.dismiss();
}
render(){
return(
<View style={styles.container}>
<TextInput style={styles.inputBox}
underlineColorAndroid='rgba(0,0,0,0)'
placeholder="Email"
placeholderTextColor = "#ffffff"
selectionColor="#fff"
keyboardType="email-address"
onChangeText={userEmail => this.setState({userEmail})}
/>
<TextInput style={styles.inputBox}
underlineColorAndroid='rgba(0,0,0,0)'
placeholder="Password"
secureTextEntry={true}
placeholderTextColor = "#ffffff"
ref={(input) => this.password = input}
onChangeText={userPassword => this.setState({userPassword})}
/>
<TouchableOpacity style={styles.button} onPress={this.login} >
<Text style={styles.buttonText}>Login</Text>
</TouchableOpacity>
</View>
)
}
async saveToStorage(userData){
if (userData) {
await AsyncStorage.setItem('user', JSON.stringify({
isLoggedIn: true,
authToken: userData.auth_token,
id: userData.user_id,
name: userData.user_login
})
);
return true;
}
return false;
}
}
And i have done the server site code like this.
*
<?php
include 'wp-load.php';
$json = file_get_contents('php://input');
$obj = json_decode($json,true);
$email = $obj['email'];
$password = $obj['password'];
$response = array(
'data' => array(),
'msg' => 'Invalid email or password',
'status' => false
);
if($obj['email']!=""){
$creds = array();
$creds['user_login'] = $email;
$creds['user_password'] = $password;
$creds['remember'] = true;
$user = wp_signon( $creds, false );
if ( is_wp_error($user) ){
echo json_encode('Wrong Details');
}
else{
$user = get_user_by( 'email', $email );
if ( $user ){
$password_check = wp_check_password( $_POST['password'], $user->user_pass, $user->ID );
if ( $password_check ){
/* Generate a unique auth token */
$token = wp_generate_password( 30 );
/* Store / Update auth token in the database */
if( update_user_meta( $user->ID, 'auth_token', $token ) ){
/* Return generated token and user ID*/
$response['status'] = true;
$response['data'] = array(
'auth_token' => $token,
'user_id' => $user->ID,
'user_login' => $user->user_login
);
$response['msg'] = 'Successfully Authenticated';
//echo json_encode($response);
}
}
}
}
}
else{
echo json_encode('try again');
}
?>
*
If you can see the both code it is written for login and save the data in the device by "async saveToStorage". But for now it giving me the error.
The error is "json parse error unexpected eof". You can in the php code, I have tried with return the data by json_encode. That did not work also. Can i get some on this. I want to know where the exact error is ? Thanks in advance.

json-parse-error-unexpected-eof it's usually
an error when you are trying to convert non covertable response to json (like html response) into json
for safety I usually convert it first to string using .then(res => res.text()) then console.log() or alert() it to prove the response is convertable to json or not without showing the react-native's red-box message,
if the response is valid json you can convert it by yourself with JSON.parse(responseText)

my problem is that's error cause for me some time for one webservice and i call that another time that's ok without changing code!!!

For me I got this issue in react once I tried to parse non existed element so I fixed this by checking if the it exists or not
if (result.data.length >0){
return JSON.parse(result.data[0].assessment)
} else {
return null
}

Related

WP API Authentication can not set the cookie

i try to make API authentication with my WP app
i have write the add the below code to add new fields and upon login it send data to External API if it user exist in API return login or create new WP user if not just don't do anything or gives an error, but i have the issue with Cookie now and get the "Error: Cookies are blocked due to unexpected output."
here is my code:
add_action('login_form', 'businessId', 10, 1);
function businessId()
{
?>
<div class="businessid_wrap">
<label for="businessId">business ID</label>
<input type="text" id="businessId" name="businessId" value=""/>
</div>
<?php
}
function au_auth($user, $username, $password)
{
$endpoint = 'will be my API endpoint url';
// Makes sure there is an endpoint set as well as username and password
if (!$endpoint || $user !== null || (empty($username) && empty($password))) {
return false;
}
$auth_args = [
'method' => 'POST',
'headers' => [
'Content-type: application/json',
],
'sslverify' => false,
'body' => [
'businessId' => $_POST['businessId'],
'userLogin' => $username,
'userPassword' => $password,
],
];
$response = wp_remote_post($endpoint, $auth_args);
$body = json_decode($response['body'], true);
var_dump ($response);
if (!$response) {
// User does not exist, send back an error message
$user = new WP_Error('denied', __('<strong>Error</strong>: Your username or password are incorrect.'));
} elseif ($response) {
/for now i just dumping the return data to check
var_dump ($response);
}
remove_action('authenticate', 'wp_authenticate_username_password', 20);
return $user;
}
add_filter('authenticate', 'au_auth', 10, 3);

WordPress/Gutenberg - permission denied to fetch users

I use Gutenberg with WordPress for a website with students.
I would like to display a list with all students (roles : student)
and exclude from the list the student who is logged in.
I tried two solutions.
First solution with getUsers() function. When I'm logged like an administrator all works fine but when a student is logged, he does not have permission to view the list. Only administrators have permission.
Second solution with a custom API route. I got a promise pending.
First solution :
import { __ } from '#wordpress/i18n';
import { CheckboxControl } from '#wordpress/components';
import { registerPlugin } from '#wordpress/plugins';
import { PluginDocumentSettingPanel } from '#wordpress/edit-post';
import { useSelect, useDispatch } from '#wordpress/data';
import { useEntityProp } from '#wordpress/core-data';
import { useState, setState, useEffect } from '#wordpress/element';
const metaboxStudents = () => {
const postType = useSelect( ( select ) => {
return select( 'core/editor' ).getCurrentPostType();
});
if ( postType !== 'subject-imposed' ) {
return null;
}
const [ meta, setMeta ] = useEntityProp( 'postType', postType, 'meta' );
const authors = useSelect( ( select ) => {
return select( 'core' ).getUsers( { roles: 'student' } );
}, [] );
if ( !posts ) {
return null;
}
const handleCheckboxChange = (data) => {
const isChecked = meta._metafield_students.some(checkedCheckbox => checkedCheckbox === data);
if (isChecked) {
setMeta( { _metafield_students: meta._metafield_students.filter( ( checkedCheckbox) => checkedCheckbox !== data) } );
} else {
setMeta( { _metafield_students: meta._metafield_students.concat(data) } );
}
};
return(
<PluginDocumentSettingPanel
name="list-students"
title={ __( 'List of students', 'ccn-gut' ) }
className='editor-styles-metabox'
>
<div className="gut-checkboxes-group">
{ posts.map( ( data ) => (
wp.data.select("core").getCurrentUser().id !== data.id
? (
<CheckboxControl
label={ data.name }
key={`student-${data.id}`}
value={ data.id }
checked={ meta._metafield_students.some(checkedCheckbox => checkedCheckbox === data.id) }
onChange={ () => handleCheckboxChange(data.id) }
/>
) : null
) ) }
</div>
</PluginDocumentSettingPanel>
);
};
registerPlugin('plugin-document-students', {
render: metaboxStudents,
icon: null
});
Second solution :
PHP for my WordPress plugin :
wp_localize_script( 'wp-api', 'wpApiSettings', array(
'root' => esc_url_raw( rest_url() ),
'nonce' => wp_create_nonce( 'wp_rest' )
));
PHP for API route :
function student_api_rest() {
register_rest_route('api/v1/', 'students', array(
'methods' => 'GET',
'callback' => 'student_api_results'
));
}
function student_api_results($data) {
....
}
index.js :
import apiFetch from '#wordpress/api-fetch';
wp.apiFetch.use( apiFetch.createNonceMiddleware( wpApiSettings.nonce ) );
const [users, setUsers] = useState( null );
useEffect( () => {
wp.apiFetch( { path: '/api/v1/students' } ).then(
(result) => {
setUsers( result );
}
)
}, []);
console.log(users);
Which solution to choose and how to resolve one of those two solutions? Permission VS promise Pending
you should be able to add capabilities to the custom user types of "students". look for where the student role was activated, it should look something like this
add_role( $role, $display_name, $capabilities );
and your looking to add list_users as a capability I believe. You can find the full list of capabilities here https://wordpress.org/support/article/roles-and-capabilities/ and heres the link directly to the list_users section of that https://wordpress.org/support/article/roles-and-capabilities/#list_users

Login WP - Connect single field to an external api

I made a plugin to allow wordpress login with external api.
Everything works, now what I have to do is that when a user logs in for the first time, the plugin checks to see if it is already present on wp, and where it was not already present, it creates a new user by taking behind username, email and password.
The new user is created but I would like it to bring with it also the id field from the external api saving it in an ACF field.
This is the code created so far:
function au_auth($user, $username, $password)
{
$options = get_option('au_options');
$endpoint = $options['au_apiurl'];
$user_email_key = 'email';
$password_key = 'password';
// Makes sure there is an endpoint set as well as username and password
if (!$endpoint || $user !== null || (empty($username) && empty($password))) {
return false;
}
// Check user exists locally
$user_exists = wp_authenticate_username_password(null, $username, $password);
if ($user_exists && $user_exists instanceof WP_User) {
$user = new WP_User($user_exists);
return $user;
}
// Build the POST request
$login_data = array(
$user_email_key => $username,
$password_key => $password
);
$auth_args = array(
'method' => 'POST',
'headers' => array(
'Content-type: application/x-www-form-urlencoded'
),
'sslverify' => false,
'body' => $login_data
);
$response = wp_remote_post($endpoint, $auth_args);
// Token if success; Not used right now
$response_token = json_decode($response['response']['token'], true);
$response_code = $response['response']['code'];
if ($response_code == 400) {
// User does not exist, send back an error message
$user = new WP_Error('denied', __("<strong>Error</strong>: Your username or password are incorrect."));
} else if ($response_code == 200) {
// External user exists, try to load the user info from the WordPress user table
$userobj = new WP_User();
// Does not return a WP_User object but a raw user object
$user = $userobj->get_data_by('email', $username);
if ($user && $user->ID) {
// Attempt to load the user with that ID
$user = new WP_User($user->ID);
}
} else {
// The user does not currently exist in the WordPress user table.
// Setup the minimum required user information
$userdata = array(
'user_email' => $username,
'user_login' => $username,
'user_pass' => $password
);
// A new user has been created
$new_user_id = wp_insert_user($userdata);
// Assign editor role to the new user (so he can access protected articles)
wp_update_user(
array(
'ID' => $new_user_id,
'role' => 'editor'
)
);
// Load the new user info
$user = new WP_User ($new_user_id);
}
}
// Useful for times when the external service is offline
remove_action('authenticate', 'wp_authenticate_username_password', 20);
return $user;
}
Anyone have any way how to help me?
Resolved! I hope this will help those who have found themselves in the same situation as me:
add_filter('authenticate', 'au_auth', 10, 3);
add_filter('register_new_user', 'au_registration', 10, 3);
// add_filter('profile_update', 'au_profile_update', 10, 3);
// add_filter('edit_user_profile_update', 'au_profile_edit', 10, 3);
function au_auth($user, $username, $password)
{
$options = get_option('au_options');
$endpoint = $options['au_apiurl'];
// Makes sure there is an endpoint set as well as username and password
if (!$endpoint || $user !== null || (empty($username) && empty($password))) {
return false;
}
$auth_args = [
'method' => 'POST',
'headers' => [
'Content-type: application/x-www-form-urlencoded',
],
'sslverify' => false,
'body' => [
'email' => $username,
'password' => $password,
],
];
$response = wp_remote_post($endpoint, $auth_args);
// Token if success; Not used right now
$response_token = json_decode($response['response']['token'], true);
$body = json_decode($response['body'], true);
$response_status_code = $response['response']['code'];
$success = $body !== 'KO';
if (!$success) {
// User does not exist, send back an error message
$user = new WP_Error('denied', __('<strong>Error</strong>: Your username
or password are incorrect.'));
} elseif ($success) {
$idExternal = $body['Id'];
$nome = $body['Name'];
$cognome = $body['Surname'];
$email = $body['Email'];
$userobj = new WP_User();
$user = $userobj->get_data_by('email', $email);
if ($user && $user->ID) {
$user = new WP_User($user->ID);
} else {
$userdata = [
'user_email' => $email,
'user_login' => join(' ', [$name, $surname]),
'user_pass' => '----',
];
$new_user_id = wp_insert_user($userdata);
$new_user_composite_id = 'user_' . $new_user_id;
update_field('field_60084ad3970a8', $idExternal, $new_user_composite_id);
update_field('field_5f22ca201c7b0', $name, $new_user_composite_id);
update_field('field_5f22ccd498f40', $surname, $new_user_composite_id);
update_field('field_5f22ce7b7c1db', $email, $new_user_composite_id);
$user = new WP_User($new_user_id);
}
}
remove_action('authenticate', 'wp_authenticate_username_password', 20);
return $user;
}

Drupal 7: How to send HTML Email

Could someone tell me what i am missing to send an HTML email using Drupal's function? Here is my call:
try{
drupal_mail('my_module', 'forgot', $node->field_email_address['und'][0]['value'], language_default(), array('reset_key' => $key),'do-not-reply#myemailaddress.com');
}catch(Exception $e){
print_r($e->getMessage());die();
}
And here is the function:
function my_module_mail($key, &$message, $params) {
$body = '<p>Click the link below to reset your password.</p>
<p>Click this link to reset your password</p>
';
// $headers = array(
// 'MIME-Version' => '1.0',
// 'Content-Type' => 'text/html; charset=UTF-8; format=flowed',
// 'Content-Transfer-Encoding' => '8Bit',
// 'X-Mailer' => 'Drupal'
// );
// $message['headers'] = $headers;
$message['subject'] = 'Why wont this send html??';
$message['headers']['Content-Type'] = 'text/html; charset=UTF-8;';
$message['body'][] = $body;
$message['from'] = 'do-not-reply#myemailaddress.com';
}
I tired just the html header and the full set that is commented out. What am I missing? The email sends fine but it's plain text. Thanks and let me know!
You can use this function
function my_module_custom_drupal_mail($target = NULL, $from = null, $subject, $message, $attachment = NULL){
$my_module = 'my_module';
$my_mail_token = microtime();
$message = array(
'id' => $my_module . '_' . $my_mail_token,
'to' => $target,
'subject' => $subject,
'body' => array($message),
'module' => $my_module,
'key' => $my_mail_token,
'from' => "$from <email#email.com>",
'headers' => array(
'From' => "$from <email#email.com>",
'Sender' => "$from <email#email.com>",
'Return-Path' => "$from <email#email.com>",
'Content-Type' => 'text/html; charset=utf-8'
),
);
if ($attachment) {
$file_content = file_get_contents($attachment[0]);
$message['params']['attachments'][] = array(
'filecontent' => $file_content,
'filename' => $attachment[1],
'filemime' => $attachment[2],
);
}
$system = drupal_mail_system($my_module, $my_mail_token);
$message = $system->format($message);
if ($system->mail($message)) {
return TRUE;
}
else {
return FALSE;
}
}
AND call it like :
$body = '<p>Click the link below to reset your password.</p>
<p>Click this link to reset your password</p>
';
$subject ='Why wont this send html??';
$from = 'myemail#email.com';
$sent = my_module_custom_drupal_mail($node->field_email_address['und'][0]['value'], $from, $subject, $body);
Customize it like you want ! :)
A few things need to be done:
/**
* Class SomeCustomModuleMailSystem Implements MailSystemInterface.
*
* Used to enable HTML email to be sent.
*/
class SomeCustomModuleMailSystem extends DefaultMailSystem {
public function format(array $message) {
$message['body'] = implode("\n\n", $message['body']);
$message['body'] = drupal_wrap_mail($message['body']);
return $message;
}
}
This to be done one time, so probably in a hook_enable or hook_update:
$current = variable_get('mail_system', ['default-system' => 'DefaultMailSystem']);
$addition = ['some_custom_module' => 'SomeCustomModuleMailSystem'];
variable_set('mail_system', array_merge($current, $addition));
Invoke hook_mail as normal, e.g.
/**
* Implements hook_mail().
*/
function some_custom_module_mail($key, &$message, $params) {
switch ($key) {
case 'some_mail_key':
$message['headers']['Content-Type'] = 'text/html; charset=UTF-8;';
$message['subject'] = $params['subject'];
$message['body'][] = $params['body'];
break;
}
}
Finally call it with something like this:
// Set variables required for the email.
$module = 'some_custom_module';
$key = 'some_mail_key';
$to = $email = 'thetoaddress#something.com';
$language = language_default();
$params['subject'] = 'Email subject';
$params['body'] = '<html><body>The HTML!</body></html>';
$from = 'thefromaddress#something.com';
$send = TRUE;
// Send the mail and log the result.
$result = drupal_mail($module, $key, $to, $language, $params, $from, $send);
if ($result['result'] === TRUE) {
watchdog('some_custom_module', 'HTML email successfully sent.', [], WATCHDOG_INFO);
}
else {
watchdog('some_custom_module', 'HTML email failed to send', [], WATCHDOG_ERROR);
}

Recursive promises in ES6 with return value(s)

I am trying to get content from GitHub (using octonode) recursively. Content is fetched recursively but the final result of the entry promise is undefined:
The function to fetch the content:
_getRepoContent ( user, repo, ref, path ) {
return new Promise( ( resolved, rejected ) => {
this._client.repo( user + "/" + repo, ref ).contents( path, ( err, data ) => {
if ( err ) {
rejected( err );
} else {
resolved( data );
}
} );
} );
}
The main recursive function:
getContentRec ( sourceDef, data ) {
var results = data || [];
return this._getRepoContent( sourceDef.user, sourceDef.repo, sourceDef.ref, sourceDef.path )
.then( ( data ) => {
let dirs = [];
results = results.concat( data );
data.forEach( ( file ) => {
if ( file.type === "dir" ) {
dirs.push( file );
}
} );
if ( dirs.length > 0 ) {
let promises = [];
dirs.forEach( ( dir ) => {
let def = {
user: sourceDef.user,
repo: sourceDef.repo,
ref: sourceDef.ref,
path: dir.path
};
promises.push( this.getContentRec( def, results ) );
} );
return Promise.all( promises );
} else {
return Promise.resolve( results );
}
} )
.catch( ( err ) => {
return Promise.reject( err );
} );
}
Calling it:
getContentRec(
{
user: "nodejs",
repo: "node"
}
}).then( (data) => {
// data is undefined
})
Any ideas? Thx a lot in advance!
Solved the problem, here's the solution ...:
getContentRec ( sourceDef ) {
return this._getRepoContent( sourceDef.user, sourceDef.repo, sourceDef.ref, sourceDef.path )
.map( ( content ) => {
let def = {
user: sourceDef.user,
repo: sourceDef.repo,
ref: sourceDef.ref,
path: content.path
};
return content.type === "dir" ? this.getContentRec( def ) : content;
} )
.reduce( ( a, b ) => {
return a.concat( b )
}, [] );
}
Note:
This solution is using bluebird and not pure ES6 promises.

Resources