1

This code is edited but comes from this site.

If I want to use a remote website to insert data using the last function from a URL link how do I do that?

My code is:

<?php

/**
 * Plugin Name: Parts Locator My Parts
 * Plugin URI: http://www.m1creative.org/
 * Description: Plugin to save and display the Parts Locator My Parts Listings
 * Version: 1.0
 * Author: Eldred Curwen
 * Author URI: http://www.m1creative.org
 * License: GPL2
 */
 /*  Copyright 2014  Eldred Curwen  (email : [email protected])

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License, version 2, as 
    published by the Free Software Foundation.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/


/**
 * Store our table name in $wpdb with correct prefix
 * Prefix will vary between sites so hook onto switch_blog too
 * @since 1.0
*/
function PL_register_my_parts_table(){
    global $wpdb;
    $wpdb->PL_my_parts = "{$wpdb->prefix}PL_my_parts";
}
add_action( 'init', 'PL_register_my_parts_table',1);
add_action( 'switch_blog', 'PL_register_my_parts_table');



/**
 * Creates our table
 * Hooked onto activate_[plugin] (via register_activation_hook)
 * @since 1.0
*/
function PL_create_my_parts_table(){

    global $wpdb;
    global $charset_collate;

    require_once(ABSPATH . 'wp-admin/includes/upgrade.php');

    //Call this manually as we may have missed the init hook
    PL_register_my_parts_table();

    $sql_create_table = "CREATE TABLE {$wpdb->PL_my_parts} (
        my_part_ID bigint(20) unsigned NOT NULL auto_increment,
        user_ID bigint(20) unsigned NOT NULL default '0',
        PL_part_ID bigint(20) NOT NULL default '0',
        part_save_date datetime NOT NULL default '0000-00-00 00:00:00',
        PRIMARY KEY  (my_part_ID),
        KEY abc (user_ID)
        ) $charset_collate; ";

    dbDelta($sql_create_table);
}
register_activation_hook(__FILE__,'PL_create_my_parts_table');

function PL_get_log_table_columns(){
    return array(
        'my_part_ID'=> '%d',
        'user_ID'=> '%d',
        'activity'=>'%s',
        'part_save_date'=>'%s',
    );
}


/**
 * Inserts a log into the database
 *
 *@param $data array An array of key => value pairs to be inserted
 *@return int The log ID of the created activity log. Or WP_Error or false on failure.
*/
function PL_insert_log( $data=array() ){
    global $wpdb;

    //Set default values
    $data = wp_parse_args($data, array(
                 'user_ID'=> get_current_user_ID(),
                 'date'=> current_time('timestamp'),
    ));

    //Check date validity
    if( !is_float($data['date']) || $data['date'] <= 0 )
        return 0;

    //Convert activity date from local timestamp to GMT mysql format
    $data['part_save_date'] = date_i18n( 'Y-m-d H:i:s', $data['date'], true );

    //Initialise column format array
    $column_formats = PL_get_log_table_columns();

    //Force fields to lower case
    $data = array_change_key_case ( $data );

    //White list columns
    $data = array_intersect_key($data, $column_formats);

    //Reorder $column_formats to match the order of columns given in $data
    $data_keys = array_keys($data);
    $column_formats = array_merge(array_flip($data_keys), $column_formats);
    $wpdb->insert($wpdb->PL_my_parts, $data, $column_formats);

    return $wpdb->insert_id;
}


/**
 * Updates an activity log with supplied data
 *
 *@param $my_part_ID int ID of the activity log to be updated
 *@param $data array An array of column=>value pairs to be updated
 *@return bool Whether the log was successfully updated.
*/
function PL_update_log( $my_part_ID, $data=array() ){
    global $wpdb;

    //Log ID must be positive integer
    $my_part_ID = absint($my_part_ID);
    if( empty($my_part_ID) )
         return false;

    //Convert activity date from local timestamp to GMT mysql format
    if( isset($data['part_save_date']) )
         $data['part_save_date'] = date_i18n( 'Y-m-d H:i:s', $data['date'], true );

    //Initialise column format array
    $column_formats = PL_get_log_table_columns();

    //Force fields to lower case
    $data = array_change_key_case ( $data );

    //White list columns
    $data = array_intersect_key($data, $column_formats);

    //Reorder $column_formats to match the order of columns given in $data
    $data_keys = array_keys($data);
    $column_formats = array_merge(array_flip($data_keys), $column_formats);

    if ( false === $wpdb->update($wpdb->PL_my_parts, $data, array('my_part_ID'=>$my_part_ID), $column_formats) ) {
         return false;
    }

    return true;
}


/**
 * Retrieves activity logs from the database matching $query.
 * $query is an array which can contain the following keys:
 *
 * 'fields' - an array of columns to include in returned roles. Or 'count' to count rows. Default: empty (all fields).
 * 'orderby' - datetime, user_ID or my_part_ID. Default: datetime.
 * 'order' - asc or desc
 * 'user_ID' - user ID to match, or an array of user IDs
 * 'since' - timestamp. Return only activities after this date. Default false, no restriction.
 * 'until' - timestamp. Return only activities up to this date. Default false, no restriction.
 *
 *@param $query Query array
 *@return array Array of matching logs. False on error.
*/
function PL_get_logs( $query=array() ){
     global $wpdb;

     /* Parse defaults */
     $defaults = array(
       'fields'=>array(),'orderby'=>'datetime','order'=>'desc', 'user_ID'=>false,
       'since'=>false,'until'=>false,'number'=>10,'offset'=>0
     );
    $query = wp_parse_args($query, $defaults);

    /* Form a cache key from the query */
    $cache_key = 'PL_logs:'.md5( serialize($query));
    $cache = wp_cache_get( $cache_key );
    if ( false !== $cache ) {
            $cache = apply_filters('PL_get_logs', $cache, $query);
            return $cache;
    }
     extract($query);

    /* SQL Select */
    //Whitelist of allowed fields
    $allowed_fields = PL_get_log_table_columns();
    if( is_array($fields) ){

        //Convert fields to lowercase (as our column names are all lower case - see part 1)
        $fields = array_map('strtolower',$fields);

        //Sanitize by white listing
        $fields = array_intersect($fields, $allowed_fields);

    }else{
        $fields = strtolower($fields);
    }

    //Return only selected fields. Empty is interpreted as all
    if( empty($fields) ){
        $select_sql = "SELECT* FROM {$wpdb->PL_my_parts}";
    }elseif( 'count' == $fields ) {
        $select_sql = "SELECT COUNT(*) FROM {$wpdb->PL_my_parts}";
    }else{
        $select_sql = "SELECT ".implode(',',$fields)." FROM {$wpdb->PL_my_parts}";
    }

     /*SQL Join */
     //We don't need this, but we'll allow it be filtered (see 'PL_logs_clauses' )
     $join_sql='';

    /* SQL Where */
    //Initialise WHERE
    $where_sql = 'WHERE 1=1';
    if( !empty($my_part_ID) )
       $where_sql .=  $wpdb->prepare(' AND my_part_ID=%d', $my_part_ID);

    if( !empty($user_ID) ){
       //Force $user_ID to be an array
       if( !is_array( $user_ID) )
           $user_ID = array($user_ID);

       $user_ID = array_map('absint',$user_ID); //Cast as positive integers
       $user_ID__in = implode(',',$user_ID);
       $where_sql .=  " AND user_ID IN($user_ID__in)";
    }

    $since = absint($since);
    $until = absint($until);

    if( !empty($since) )
       $where_sql .=  $wpdb->prepare(' AND part_save_date >= %s', date_i18n( 'Y-m-d H:i:s', $since,true));

    if( !empty($until) )
       $where_sql .=  $wpdb->prepare(' AND part_save_date <= %s', date_i18n( 'Y-m-d H:i:s', $until,true));

    /* SQL Order */
    //Whitelist order
    $order = strtoupper($order);
    $order = ( 'ASC' == $order ? 'ASC' : 'DESC' );
    switch( $orderby ){
       case 'my_part_ID':
            $order_sql = "ORDER BY my_part_ID $order";
       break;
       case 'user_ID':
            $order_sql = "ORDER BY user_ID $order";
       break;
       case 'datetime':
             $order_sql = "ORDER BY part_save_date $order";
       default:
       break;
    }

    /* SQL Limit */
    $offset = absint($offset); //Positive integer
    if( $number == -1 ){
         $limit_sql = "";
    }else{
         $number = absint($number); //Positive integer
         $limit_sql = "LIMIT $offset, $number";
    }

    /* Filter SQL */
    $pieces = array( 'select_sql', 'join_sql', 'where_sql', 'order_sql', 'limit_sql' );
    $clauses = apply_filters( 'PL_logs_clauses', compact( $pieces ), $query );
    foreach ( $pieces as $piece )
          $$piece = isset( $clauses[ $piece ] ) ? $clauses[ $piece ] : '';

    /* Form SQL statement */
    $sql = "$select_sql $where_sql $order_sql $limit_sql";
    if( 'count' == $fields ){
        return $wpdb->get_var($sql);
    }

    /* Perform query */
    $logs = $wpdb->get_results($sql);

    /* Add to cache and filter */
    wp_cache_add( $cache_key, $logs, 24*60*60 );
    $logs = apply_filters('PL_get_logs', $logs, $query);

    return $logs;
 }


/**
 * Deletes an activity log from the database
 *
 *@param $my_part_ID int ID of the activity log to be deleted
 *@return bool Whether the log was successfully deleted.
*/
function PL_delete_log( $my_part_ID ){
    global $wpdb;

    //Log ID must be positive integer
    $my_part_ID = absint($my_part_ID);

    if( empty($my_part_ID) )
         return false;

    do_action('PL_delete_log',$my_part_ID);

    $sql = $wpdb->prepare("DELETE from {$wpdb->PL_my_parts} WHERE my_part_ID = %d", $my_part_ID);

    if( !$wpdb->query( $sql ) )
         return false;

    do_action('PL_deleted_log',$my_part_ID);

    return true;
}

 if ( isset( $_GET['action'] ) && $_GET['action'] == 'insert') {

    $user_ID = get_current_user_id();
    $PL_part_ID = $_GET["partID"];

    PL_insert_log ( array(
        'user_ID'=> $user_ID,
        'PL_part_ID'=> $PL_part_ID,
    ));

 }

?>

If I want to use a remote website to insert data using the last function from a URL link how do I do that?

I have now made my insert code this and it is in a page template so that I can link from another site and insert data, however I would like to try and make it more secure.

if (isset($wp_query->query_vars['action']) )
{
    if ($wp_query->query_vars['action'] == 'insert')
    {

        $user_ID = get_current_user_id();
        $PL_part_ID = $wp_query->query_vars['partID'];
        $part_save_date = date('d.m.y h:i:s');
        global $wpdb;
        $wpdb->insert( 'wp_pl_my_parts', array( 'user_ID' => $user_ID, 'PL_part_ID' => $PL_part_ID, 'part_save_date' => $part_save_date ), array( '%d', '%d', '%s' ) );
    }

}
4
  • 1
    Can you be more specific as to what you mean by "last function from a URL"? There are many ways to insert data programmatically via a remote location. Ideally we need to see the code you are working with on the remote side more so than the plugin above that handles the insertion on the target site.
    – Adam
    Commented Jun 20, 2014 at 6:59
  • Now using this in a page template Commented Jun 21, 2014 at 3:57
  • You should not add code to comments. File an edit on your question and add any extra code/info to your question Commented Jun 21, 2014 at 5:31
  • 1
    No functionality should reside in a (theme) template. What you are trying to do is not good. Put code like this always in plugin. And nowhere else.
    – kaiser
    Commented Jun 21, 2014 at 13:40

1 Answer 1

2

Ok, first of all, lets (temporarily) disregard the code from wptuts-user-log so as not to confuse that code with the basic objective first.

For the record however, that code was written by our very own Stephen Harris, an updstanding member of this community and the WordPress community at large. The particular link question was part of a tutorial series on Creating Custom Database Tables.

So...

As I mentioned in my earlier comment to you, there are many ways to insert data from a remote site, I'm going to cover a very basic way in which you can achieve this.

I'll give fair warning that the following example code makes no assumption about security, data validation and sanitization, with the exception of using $wpdb->prepare, the ultimate responsibility will lay with you to ensure your application is secure.

In order for us to help you more precisely with your implementation of remote insertion requests we need some context as to how your implementation is intended to work. For example, what kind of people are allowed to make such requests, what limitations you would like imposed on those requests and any other relevant information to the problem.

That aside, I strongly recommend not including the code you have exampled in a theme template file, certainly not a page template file. If that page is accessible on the front end of your site which I assume to be the case, it may be possible for anyone to access that URL and initiate insertion requests to your database not to mention potentially hack the sh*t out of you.

Instead of handling this functionality in your theme, I suggest creating a plugin.

<?php
/*
Plugin Name: Plugin Name
Plugin URI: http://www.yoursite.com/
Description: Remote Insert
Author: Your Name
Version: 1.0
Author URI: http://yoursite.com
*/

add_action( 'plugins_loaded', array( RemoteRequest::instance(), 'setup' ));

class RemoteRequest {

    public function __construct() {}

    public function setup() {

        add_filter( 'init', array($this, 'rewrite_rules'));

        add_filter( 'query_vars', array($this, 'add_query_vars'), 10, 1);

        add_action( 'parse_request', array($this, 'parse_request') );

    }

    public static function instance() {

       NULL === self::$instance and self::$instance = new self;
       return self::$instance;

    }

    public function rewrite_rules() {

        //http://www.yoursite.com/remote/insert
        //http://www.yoursite.com/remote/update
        //http://www.yoursite.com/remote/delete
        //etc...

        add_rewrite_rule( 
            '^remote/(insert|update|delete)/?$', 
            'index.php?remote_request=true&remote_action=$matches[1]', 
            'top' 
        );

    }

    public function add_query_vars($query_vars) {

        $query_vars[] = 'remote_request';
        $query_vars[] = 'remote_action';

        return $query_vars;

    }

    public function parse_request($wp) {

        $query = $wp->query_vars;

        if( array_key_exists( 'remote_insert', $query ) && isset($query['remote_action']) ) {

            //it would be very wise to check the origin of the
            //request at this point in addition to the existence
            //of a valid API key prior to continuing execution.    

            if ( $query['remote_action'] === 'insert' ) {

                if ( $this->insert_data($_POST) ) {

                    //on success redirect user to success link
                    wp_redirect($success_link);
                    exit;

                } else {

                    //on success redirect user to success link
                    wp_redirect($failed_link);
                    exit;

                }

            } elseif ( $query['remote_action'] === 'update' ) {

                //your update code...

            } elseif ( $query['remote_action'] === 'delete' ) {

                //your delete code...

            } else {

                //handle other condtions...

            }

        }

    }

    public function insert_data($data) {

        global $wpdb;

        $result = $wpdb->query( $wpdb->prepare( 
                "
                    INSERT INTO $wpdb->yourcustomtable
                    ( user_ID, PL_part_ID, part_save_date )
                    VALUES ( %d, %d, %s )
                ", 
                $data['user_id'], 
                $data['pl_part_id'], 
                $data['part_save_date ']
            )
        ); 

        return $result;

    }


}

...the above is only a rough example, not neccessarily the best.

Extrapolating remote API requests into there own plugin will make your code and implementation much more maintainable and interoperable with site changes (especially changing themes as you wont lose your remote capabilities).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.