I have this row in a database
and I want to be able to change the values in each block (e.g. [license_civ_driver,1]) through a page on a website. The full cell in the database can be seen here.
"[[`license_civ_driver`,1],[`license_civ_boat`,0],[`license_civ_pilot`,1],[`license_civ_advpilot`,1],[`license_civ_trucking`,1],[`license_civ_gun`,1],[`license_civ_hunting`,0],[`license_civ_dive`,0],[`license_civ_home`,0],[`license_civ_platinum`,1],[`license_civ_oil`,1],[`license_civ_diamond`,0],[`license_civ_salt`,0],[`license_civ_sand`,0],[`license_civ_iron`,0],[`license_civ_copper`,1],[`license_civ_cement`,0],[`license_civ_rubber`,0],[`license_civ_meth`,0],[`license_civ_cocaine`,0],[`license_civ_heroin`,0],[`license_civ_marijuana`,0],[`license_civ_rebel`,0],[`license_civ_advrebel`,0]]"
(I already have all the database connections set up, I just need the query and PhP code to do as I mention).
I also want to make each block translate into text (e.g. license_civ_driver will be Driver License).
As well as that, I want to display each block as a div and have the background change colour based on the number within the block.
I know this is probably a huge ask but I have tried everything to my knowledge including using sites to help me do it myself (this is my attempt). If anyone can help me do it then I would be extremely grateful. If someone wants to make it for me then I would greatly appreciate that but obviously I want to learn so I'd rather be helped.
Thanks in advance!
I notice in your code that you are including many files inside a loop - some inside other loops... this is NOT the way to do it I would say. Also I believe it is something of a mistake to say "I'll sort that ( sql injection ) out later" considering "...obviously I want to learn so I'd rather be helped."
It would be better to adopt the good practises early, do it right and then not have to go back.
That said perhaps the following might be of use based upon the comments in the question rather than in-depth studying of the php.
update:
After reading your comment I added some hastily written javascript code ( and made a minor change to the php generated html ) - it's not tested mor ethan a simple click but should give the mechanism by which you can accomplish the stated goal. Use the request to trigger some PHP code ( same page or other script... ) - validate parameters/data sent, construct sql prepared statement and execute.
/* some rudimentary styles for demo purposes */
echo "
<style>
.class_low{padding:1rem;width:100%;background:rgba(255,0,0,0.25);}
.class_medium{padding:1rem;width:100%;background:rgba(0,0,255,0.25);}
.class_high{padding:1rem;width:100%;background:rgba(0,255,0,0.25);}
.unknown{padding:1rem;width:100%;background:yellow}}
</style>
<script>
const buildparams=function(p){
if( p && typeof( p )==='object' ){
p=Object.keys( p ).map(function( k ){
return typeof( p[ k ] )=='object' ? buildparams( p[ k ] ) : [ encodeURIComponent( k ), encodeURIComponent( p[ k ] ) ].join('=')
}).join('&');
}
return p;
};
const ajax=function(url,params,callback){
let xhr=new XMLHttpRequest();
xhr.onload=function(){
if( this.status==200 && this.readyState==4 )callback.call( this, this.response )
};
xhr.onerror=function(e){
alert(e)
};
xhr.open( 'POST', url, true );
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
xhr.setRequestHeader('X-Requested-With','XMLHttpRequest');
xhr.send( buildparams( params ) );
};
const evtcallback=function(r){
alert(r);
};
const evtbindclicks=function(div){
div.addEventListener( 'click', evtclickhandler, false );
};
const evtclickhandler=function(e){
let url=document.location.href;
let params={ licence:this.innerHTML, value:this.dataset.value };
ajax.call( this, url, params, evtcallback );
};
document.addEventListener('DOMContentLoaded',function(){
Array.prototype.slice.call( document.querySelectorAll('.class_low, .class_medium, .class_high, .unknown') ).forEach( evtbindclicks );
},false );
</script>";
/* a lookup object to choose correct style based upon integer value */
$matrix=array(
0 => 'class_low',
1 => 'class_medium',
2 => 'class_high'
);
/* fudge around with the database column data. It would be so much easier if the data were originally json in the db! */
function makejson( $colval, $arr ){
$colval=str_replace( array( '"', '`','_' ),array('',"#",' ' ), $colval );
return json_decode( str_replace( $arr,'', str_replace( '#', '"', $colval ) ) );
}
/* words to replace in data */
$arrchrs=array('civ','license');
/* source data - ie: column data from db */
$colval="[[`license_civ_driver`,1],[`license_civ_boat`,2],[`license_civ_pilot`,15],[`license_civ_advpilot`,0],[`license_civ_trucking`,1],[`license_civ_gun`,1],[`license_civ_hunting`,0],[`license_civ_dive`,0],[`license_civ_home`,0],[`license_civ_platinum`,1],[`license_civ_oil`,1],[`license_civ_diamond`,0],[`license_civ_salt`,0],[`license_civ_sand`,0],[`license_civ_iron`,0],[`license_civ_copper`,1],[`license_civ_cement`,0],[`license_civ_rubber`,0],[`license_civ_meth`,0],[`license_civ_cocaine`,0],[`license_civ_heroin`,0],[`license_civ_marijuana`,0],[`license_civ_rebel`,0],[`license_civ_advrebel`,0]]";
/* attempt to make the above usable */
$json=makejson( $colval, $arrchrs );
/* process the data, create a new div per item and assign class using matrix */
foreach( $json as $arr ){
$class = isset( $matrix[ $arr[1] ] ) ? $matrix[ $arr[1] ] : 'unknown';
$name = $arr[0];
printf( '<div class="%s" data-value="%d">%s Licence</div>', $class, $arr[1], ucwords( $name ) );
}
This will yield something like this:
Related
I'm trying to use the alphavantage REST API to output stock prices through Advanced Custom Fields. My issue right now is that I don't know how I can create a list of stocksymbol names (we have specific stocks we want to check) that changes each call until all stocks have been checked.
This is my current Wordpress Code in functions.php
/* Register Stock Price Custom Post Type */
add_action('init', 'register_aktienpreise_cpt');
function register_aktienpreise_cpt(){
register_post_type('aktienpreise', [
'label' => 'Aktienpreise',
'public' => true,
'capability_type' => 'post'
]);
}
add_action( 'wp_ajax_nopriv_get_aktienpreise_from_api', 'get_aktienpreise_from_api' );
add_action( 'wp_ajax_get_aktienpreise_from_api', 'get_aktienpreise_from_api' );
/* Initialize Function */
function get_aktienpreise_from_api(){
/* Set Log File */
$file = get_stylesheet_directory() . '/report.txt';
/* Declare Current Symbol Variable and check if its not empty */
$current_symbol = ( ! empty($_POST['current_symbol']) ) ? $_POST['current_symbol'] : '';
$aktienpreise = [];
/* Results output for AlphaVantage Rest API + APIKEY - Add Current Symbol Set for each API Call */
$results = wp_remote_retrieve_body( wp_remote_get('https://www.alphavantage.co/query?function=GLOBAL_QUOTE&apikey=demo&symbol=' . $current_symbol_set ));
file_put_contents($file, "Current Symbol: " . $current_symbol. "\n\n", FILE_APPEND);
// turn it into a PHP array from JSON string
$results = json_decode( $results );
// Either the API is down or something else spooky happened. Just be done.
if( ! is_array( $results ) || empty( $results ) ){
return false;
}
/* Change Current Stock Symbol for the next call until empty */
$current_symbol = $current_symbol + $current_symbol_set;
/* Repeat Calls until results are empty */
wp_remote_post( admin_url('admin-ajax.php?action=get_aktienpreise_from_api'), [
'blocking' => false,
'sslverify' => false,
'body' => [
'current_symbol' => $current_symbol
]
] );
}
At this part
/* Change Current Stock Symbol for the next call until empty */
$current_symbol = $current_symbol + $current_symbol_set;
I'd like to have a list of specific stocks I want to check (for example Apple, IBM etc.).
The goal is that on each call the variable changes to the next stock (lets say first call Apple, second IBM), then writes those into the specific ACF Fields that I can showcase in a table on our website.
If the restapi urls would just have number increases it would be easy, but how do I do it with specific terms like "IBM" etc.
Furthermore if there are easier solutions to this please tell me so since I'm fairly new to REST APIs.
The Goal in general is to just display current stockprices of specific stocks inside a table on our website, preferably inside an ACF Field so we can do math formulas on the price (for example price x 2 for another table field).
Thanks for everyone taking their time to help me out!
Why don't you use an array for the stock symbols and do the AlphaVantage API calls inside a loop?
I will give you a quick example:
$my_symbols = [
'IBM',
'Microsoft',
'Tata'
];
foreach( $my_symbols as $current_symbol ) // iterate through the array elements
{
//... make the API calls to AlphaVantage
//... do any other business logic, like storing the API result in file or update the stocks, etc..
}
One thing to keep in mind is that you should make sure the script won't get a timeout. So increase the max_execution_time to a higher value.
Also, you don't have to call your own API here. I mean you don't have to do the wp_remote_post() to your own website.
Im trying to update the mini-cart (cart_fragments) after/on an ajax event. It works like this.
HTML Trigger:
<a id="woomps-button-\'.$nr.\'" class="woomps-button" '.$ajax_url.' data-button-nr="'.$nr.'">
jQuery request:
jQuery( document ).on('click', '.woomps-button', function() {
var nr= jQuery(this).data('button-nr');
jQuery.ajax({
url : subpost.ajax_url,
type : 'post',
data : {
action : 'woomps_update_nr',
security : subpost.security,
nr: nr
},
success : function( response ) {
window.alert(nr);
//MAYBE_code to refresh_fragments here
}
});
return false;
});
PHP responder:
function woomps_update_choosen_person () {
$p = $_POST['nr'];
if ($p == 1) {$x= "This must show in cart";}
WC()->session->set( 'woomps_limit_by_persons' , $x );
//MAYBE code to refresh_fragments here
}
And in the mini-cart.php template i have a calculation based on this field.
$items_left_start = WC()->session->get( 'woomps_limit_by_persons' )?: 3 ;
//Do something something here
So this works, except I need to refresh the cart like when an item is added to cart. My assumption is that is should be an ajax request from jQuery that i can put in the success block?
The class i (think) I want to fire is this WC_AJAX::get_refreshed_fragments(); But this is fired from an an add_action, so i tried this add_action( 'wp_ajax_nopriv_woocommerce_get_refreshed_fragments', array( 'WC_AJAX', 'get_refreshed_fragments' ) );. But it did not work either.
I also try to create an jQuery ajax call like it does in the add_to_cart button, but it neither worked.
//MAYBE_code to refresh_fragments here
var data = {};
jQuery.post(
wc_get_refreshed_fragments_params.wc_ajax_url.toString().
replace( '%%endpoint%%', 'get_refreshed_fragments' ), data,
function( response ){
})
}
I do not completely understand how this works, if anyone have some pointers or a snippet i would so much appriciate it. Been struggeling with this for some time now.
After much struggeling this topic on stack helped create the correct code to update mini cart fragments. It was both PHP and jQuery neeeded.
So basically you can call the WC_AJAX::get_refreshed_fragments() at the end of your PHP coode responder; if it comes from an AJAX call. It will not return to your PHP responder code so put it at the end. The PHP respons will end/sent back to jQuery inside the WC_AJAX::get_refreshed_fragments(); so you also need to create some jQuery that responds to this. This i got from the topic:
var fragments = response.fragments;
if ( fragments ) {
jQuery.each(fragments, function(key, value) {
jQuery(key).replaceWith(value);
});
}
I am trying to create a wordpress theme. i would like to have three columns with post excerpts. But the problem is that they don't always have the same height (and i don't want them to), so when in one row a post is too high, the next row will start too far away.
Hmmm, i can really explain it, so i created this fiddle to show what i mean:
//in the fiddle there is html and css making a clear example of what i mean
http://jsfiddle.net/59qyD/1/
As you can see post id#5 is too long, so post #7 doesn't go any more under post #4.
What i would like is to find a solution where the post always "go up" to the previous post in that column. If possible, without any plugins...
Any ideas?
To create a dynamic column height no matter if it's images/posts/products, you can apply Masonry JS
This JS offers you the possibility to fit each new div under the previous div from the above line, and has a great effect of showing it.
Here is a PHP + CSS based solution:
PHP:
$count = 0;
$count_total = 10; // or use dynamic count: count($all_posts)
$columns = 3;
foreach ( $all_posts as $k=>$v ) {
$count++;
$is_first_column = false; // always set to false, then set to true only when the condition matches!
// Now check is this a post for the first column
if( $count==1 || ($count-1)%$columns==0 ) { // check if it's 1st and every 4,7,10 post and place it in 'column 1'
// set additional class for every post that need to be placed in the first column
$is_first_column = true;
}
// Now you can add the additional class to the html markup:
<article id="post-<?php the_ID(); ?>" class="post col<?php if( !empty( $is_first_column ) ) { echo ' column_1'; } ?>">
}
And then use CSS to clear the float for every .column_1.
CSS:
.column_1 {
clear: both;
}
I used similar approach in multiple projects and it worked. The code above may need to me modified a bit to work for your specific theme, but I hope you'll get the main idea.
It will work immediately after page + CSS load (no waiting for JS to load)! :-)
Here's the scenario: I'm building a Wordpress plugin to manage some survey research that I'm involved in. The project admin is able to upload a csv file from the WP admin interface. On the client side, when the file is uploaded it goes through each line of the file, extracts the necessary info about the users and then makes an AJAX call to add the participant to the project. I decided to parse the csv file on the client side and submit the ajax requests one by one so that I could update a progress bar as each returns. The javascript looks like this:
$( '#csv_upload_button' ).click( function() {
// declare the necessary variables
var f = $( '#csv_file_input' )[0].files[0],
fr = new FileReader,
rows, headers, dialog, count, remaining;
// when the file loads
fr.onload = function() {
// get the rows, the count, number remaining to process, and headers
rows = fr.result.split( "\n" );
remaining = count = rows.length - 1; // -1 to account for header row
headers = $.trim( rows[0] ).split( ',' );
// create the dialog box to show the progress bar
dialog = $( '<div></div>' )
.html(
'<p>Loading...</p>' +
'<p><progress id="csv_upload_progress" max="' + count +
'" min="0" value="0"></p>' )
.dialog( { modal: true; } );
// then for each row in the file
$( rows ).each( function( i, r ) {
// create an object to hold the data
var data = {}, row = $.trim( r ).split( ',' ), j;
if ( i > 0 ) { // data starts on the second row
// map the data into our object
for ( j = 0; j < headers.length; j++ ) {
data[ headers[ j ] ] = row[ j ];
}
// send it to the server
$.post(
ajaxurl,
{
action: 'import_panel_member',
data: data,
postid: $( '#post_ID' ).val()
},
function( result ) {
var prog = $( '#csv_upload_progress' );
prog.attr( 'value', prog.attr( 'value' ) + 1 );
if ( 0 == --remaining ) {
// stuff to do when everything has been loaded
}
}
);
}
});
};
// read the csv file
fr.readAsText( f );
});
The PHP looks something like this:
function import_panel_member() {
header( 'content-type: application/json' );
// get the variables sent from the client
$postid = $_POST[ 'postid' ];
$data = $_POST[ 'data' ];
/*
* ...do other things involving talking to a 3rd party server...
*/
// get the WP meta data variable to be updated
$participants = get_post_meta( $postid, '_project_participants', true );
// modify it
$participants[] = $data;
// update the database
update_post_meta( $postid, '_project_participants', $participants );
// return a message to the client
echo json_encode( (object) array( 'success' => 1, 'message' => 'added' ) );
exit;
}
The problem is that since these requests happen asynchronously, it appears that the _project_participants metadata field is only being updated by the last record to be processed. In other words, only the last person in the list shows up in the list of participants. Here are some things that I've tried:
Change $.post() to $.ajax() and set async: false
This works but it's much slower (due to synchronous calls) and for some reason it prevents my dialog box from showing up until after all the ajax calls have finished.
Upload the entire csv file to the server and deal with it there
Instead of parsing the csv on the client side. This works, too, but I don't think I can get intermediate feedback from the server that I can use to update the progress bar. This request can take quite a while, and I don't want users to "give up" on the request before it's complete. When doing it this way, sometimes the server never responds to the ajax call.
So perhaps I am greedy and just want my cake and to eat it, too. How can I take advantage of the speed of asynchronous requests, which give me the opportunity to give the user feedback with a progress bar, but not screw myself up with concurrency issues on the server?
I figured it out. The answer was a hybrid of the two methods. I can use a series of $.post() calls to do the stuff that works better in async mode, and then upload the whole csv to do the stuff that works better in sync mode. Never would have figured this out without typing out the whole explanation in SO!
i have made this example work on my page http://datatables.net/examples/server_side/server_side.html, (using php5, jquery+ui and dataTables.net)
i would like to be able to add a Modify and Delete link on each row, how can i do that without sending two extra columns with the links from the server?
also how can i substitute the ids the rows have in the database and that are sent by the server with nice number starting from 1 till iTotalDisplayRecords...
thank you
found how
var controller_name = '<?php echo Zend_Controller_Front::getInstance()->getRequest()->getControllerName();?>';
"fnDrawCallback": function ( oSettings ) {
/* Need to redo the counters if filtered or sorted */
for ( var i=0, iLen=oSettings.aiDisplay.length ; i<iLen ; i++ )
{
var link = $(' Modifica Cancella');
$('td:eq(0)', oSettings.aoData[ oSettings.aiDisplay[i] ].nTr ).html( i+1 );
$('td:eq(0)', oSettings.aoData[ oSettings.aiDisplay[i] ].nTr ).append(link);
}
},