How to improve/shorten PHP code syntax? Wordpress example - php

I have used browserstack many times for idea's and bugs. I'm at an ok level now but I like to hone my skills.
The following code is a custom piece of coding I have done to a template. It works perfectly. How can I improve this code? It seems way to long for what I'm trying to achieve. How can I shorten this code?
// Display treatments specialism icons that a location is practising
// Fetch all the entries from WP database
function get_specs($location_id) {
//Register globals
global $wpdb;
// The query
$sql = "SELECT * FROM $wpdb->postmeta";
// Get the results array from the query
$results = $wpdb->get_results($sql) or die(mysql_error());
// Assign the results array and iterate 1 by one
foreach( $results as $results ) {
$meta_key = $results->meta_key;
// Every time the key value is a 'naam' (name) check wether this is the name of a specialism.
// The names are not gotten by certain id's because or flexibility (Client add more/change spacialisms later without programming intervention)
if ($meta_key == "naam") {
// The name value to be compared
$specialismen_naam = $results->meta_value;
// Store the ID connected to the found naam for later use
$specialismen_id = $results->post_id;
// Fetch the specialism meta_value array of all the locations, all specialisms practised are in 1 array
$specialismen = get_post_meta($location_id, 'specialiteiten', true);
// Search location specialism array and compare it with the name value. if it has a match continue
if (in_array($specialismen_naam, $specialismen)) {
// Get the specialism image from the earlyer stored id
$thumbnail_image = get_post_meta( $specialismen_id, 'thumbnail_image', true );
// Get the link to the specialism page for if clicked
$link = get_page_link(get_post_meta( $specialismen_id, 'link', true ));
//display the specialism icon with link to specialism page
echo '<li>'. wp_get_attachment_image( $thumbnail_image, array(30,30) ) .'</li>';
}
}
}
}
// Get the Locations
// Fetch the data
function get_location_fp($object_ids) {
// register globals
global $wpdb;
// Query
$sql = "SELECT * FROM $wpdb->postmeta WHERE post_id = $object_ids";
// Results
$results = $wpdb->get_results($sql) or die(mysql_error());
foreach( $results as $results ) {
$meta_key = $results->meta_key;
$meta_value = $results->meta_value;
// If there is a location thumbnail assigned (has to be), process
if ($meta_key == "lokatie_thumbnail") {
// fetch displayed data from event in variable. Telephone, address, name, link to location page
$telefoonnummer = get_post_meta( $object_ids, 'telefoonnummer', true );
$adres = get_post_meta( $object_ids, 'adres', true );
$naam = get_post_meta( $object_ids, 'naam', true );
$link = get_page_link(get_post_meta( $object_ids, 'link', true ));
// Fetch thumbnail image of each location
$thumbnail_image = get_post_meta( $object_ids, 'lokatie_thumbnail', true );
// Display the location
echo '<div id="lokatie-fp"><div class="lokatie-image">'. wp_get_attachment_image( $thumbnail_image ) .'</div><div class="lokatie-gegevens"><h3>'. $naam .'</h3><p>'. $telefoonnummer .'</p><p>'. $adres .'</p>';
// Add all specialisms that are practised at this location
echo '<ul>'. get_specs($object_ids) .'</ul></div></div></a>';
}
}
}
// Called somewhere in template:
<?php get_location_fp(62); ?>
<?php get_location_fp(67); ?>
<?php get_location_fp(105); ?>
<?php get_location_fp(104); ?>

Indenting your code consistently will make it much easier to read/debug
// Display treatments specialism icons that a location is practising
// Fetch all the entries from WP database
function get_specs($location_id) {
//Register globals
global $wpdb;
// The query
$sql = "SELECT * FROM $wpdb->postmeta";
// Get the results array from the query
$results = $wpdb->get_results($sql) or die(mysql_error());
// Assign the results array and iterate 1 by one
foreach( $results as $results ) {
$meta_key = $results->meta_key;
// Every time the key value is a 'naam' (name) check wether this is the name of a specialism.
// The names are not gotten by certain id's because or flexibility (Client add more/change spacialisms later without programming intervention)
if ($meta_key == "naam") {
// The name value to be compared
$specialismen_naam = $results->meta_value;
// Store the ID connected to the found naam for later use
$specialismen_id = $results->post_id;
// Fetch the specialism meta_value array of all the locations, all specialisms practised are in 1 array
$specialismen = get_post_meta($location_id, 'specialiteiten', true);
// Search location specialism array and compare it with the name value. if it has a match continue
if (in_array($specialismen_naam, $specialismen)) {
// Get the specialism image from the earlyer stored id
$thumbnail_image = get_post_meta( $specialismen_id, 'thumbnail_image', true );
// Get the link to the specialism page for if clicked
$link = get_page_link(get_post_meta( $specialismen_id, 'link', true ));
//display the specialism icon with link to specialism page
echo '<li>'. wp_get_attachment_image( $thumbnail_image, array(30,30) ) .'</li>';
}
}
}
}
// Get the Locations
// Fetch the data
function get_location_fp($object_ids) {
// register globals
global $wpdb;
// Query
$sql = "SELECT * FROM $wpdb->postmeta WHERE post_id = $object_ids";
// Results
$results = $wpdb->get_results($sql) or die(mysql_error());
foreach( $results as $results ) {
$meta_key = $results->meta_key;
$meta_value = $results->meta_value;
// If there is a location thumbnail assigned (has to be), process
if ($meta_key == "lokatie_thumbnail") {
// fetch displayed data from event in variable. Telephone, address, name, link to location page
$telefoonnummer = get_post_meta( $object_ids, 'telefoonnummer', true );
$adres = get_post_meta( $object_ids, 'adres', true );
$naam = get_post_meta( $object_ids, 'naam', true );
$link = get_page_link(get_post_meta( $object_ids, 'link', true ));
// Fetch thumbnail image of each location
$thumbnail_image = get_post_meta( $object_ids, 'lokatie_thumbnail', true );
// Display the location
echo '<div id="lokatie-fp"><div class="lokatie-image">'. wp_get_attachment_image( $thumbnail_image ) .'</div><div class="lokatie-gegevens"><h3>'. $naam .'</h3><p>'. $telefoonnummer .'</p><p>'. $adres .'</p>';
// Add all specialisms that are practised at this location
echo '<ul>'. get_specs($object_ids) .'</ul></div></div></a>';
}
}
// Called somewhere in template:
<?php get_location_fp(62); ?>
<?php get_location_fp(67); ?>
<?php get_location_fp(105); ?>
<?php get_location_fp(104); ?>
Sometimes it can be easier to read if you can avoid doing nested if statements, for example:
if ($meta_key != "naam") {
continue;
}
directly echoing out can sometimes be a bit confusing and can lead to output being sent when not desired (say if an error occurs). I quite like to build up an array of the output before rendering that:
$output = array();
$output[] = '<li>'. wp_get_attachment_image( $thumbnail_image, array(30,30) ) .'</li>';
...
...
echo implode(PHP_EOL,$output);
Other than those minor things I'd say its fine. It's really nice and verbose, easy to read, well documented.
As for Jalpa's comments I'd say that its good practice to have the SQL query and the execution of it on different lines, it improves readability. And there's no need for an if condition before the foreach, that takes care of itself.
Edit
You mentioned your li's are being rendered early. From your function get_specs() you certainly don't want to render anything but here you can return your output to the get_location_fp() calling function.
function get_specs($loctation_id) {
...
$output = array();
...
$output[] = '<li>'. wp_get_attachment_image( $thumbnail_image, array(30,30) ) .'</li>';
...
return implode(PHP_EOL,$output);
}
function get_location_fp($object_ids) {
...
$output[] = '<ul>'. get_specs($object_ids) .'</ul></div></div></a>';
...
}
By returning the output from get_specs() rather than rendering it, it will be inserted between the uls and not before it.

I think you need to add below changes :
1) Please write query like this $wpdb->get_results("SELECT * FROM $wpdb->postmeta") no need to write in two lines.
2) please put if condition before foreach is not empty or count() array > 0.

Related

Add result of php function to WP database

I have the following function to create a member_id:
add_action('user_register', 'generate_member_id');
function generate_member_id($user_id){
$unique_id = 1000 + get_current_user_id();
$chapter_id = fetch_chapter();
$member_id = "FAL-" . $chapter_id . "-" . $unique_id;
return $member_id;
}
It appears to work fine and I can call the function from a shortcode and get the correct value.
Now I want to add the returned value to a database and have tried using
update_user_meta()
$wpdb->update
$wpdb->insert
$wpdb->query
all with necessary arguments but nothing seems to work.
I expected this to do it, but it just generates a generic error that I am not able to debug (I have a problem with error logging):
global $wpdb;
$users = $wpdb->get_results( "SELECT ID FROM $wpdb->users" );
$generated_id = generate_member_id()
if( $users ) {
foreach ( $users as $user ) {
update_user_meta( $user->ID, 'member_id', generate_member_id() );
}
}
However if I change generate_member_id() to a string like 'memberId', it works and the database is updated. So I don't know what I'm doing wrong. Why can't I add' the result of the generate_member_id() function and to a WP database?
EDIT
add_action('user_register', 'fetch_chapter');
function fetch_chapter(){
$current_user = wp_get_current_user();
$current_user_id = $current_user->ID;
global $wpdb;
$result = $wpdb->get_results('SELECT meta_value FROM usermeta WHERE meta_key = \'chapter_name\' AND user_id = '. $current_user->ID .' LIMIT 1');
if ($result[0]->meta_value == 'Peregrine') {
$result[0]->meta_value = 'PG';
}elseif ($result[0]->meta_value == 'Barbary') {
$result[0]->meta_value = 'BB';
}
return $result[0]->meta_value;
}
There are a few things I notice that could cause problems:
You have this line that (1) has no ; at the end and (2) it doesn't look like you need it anyway - you don't use $generated_id anywhere:
$generated_id = generate_member_id()
You are not passing the user_id into generate_member_id for your users in the loop calling update_user_meta...
... but even if you did pass in the user_id, generate_member_id isn't using it anyway - it is using the current user id. That is the wrong value for the users in your loop.
You need to fix your generate_member_id function to work with the user_id parameter. I assume you want this function to work without one too, so it still gets the get_current_user_id is no user id is passed in:
add_action('user_register', 'generate_member_id');
function generate_member_id($user_id){
// If no user_id is passed in, use the current user id
if (!$user_id) $user_id = get_current_user_id();
$unique_id = 1000 + $user_id;
$chapter_id = fetch_chapter_id();
$member_id = "FAL-" . $chapter_id . "-" . $unique_id;
return $member_id;
}
And then remove the erroneous $generated_id... line and pass the user_id to the generate_member_id in your update_user_meta:
global $wpdb;
$users = $wpdb->get_results( "SELECT ID FROM $wpdb->users" );
if( $users ) {
foreach ( $users as $user ) {
update_user_meta( $user->ID, 'member_id', generate_member_id($user->ID) );
}
}

Inserting multiple checkbox values in mysql

i have a joomla component for making appointments and i have checkboxes for starting dates of the appointments...my problem is that i can only make one appointment at a time,i want to be able to check multiple boxes so the values for those boxes can be saved in mysql,when i check multiple checkboxes only the last checked is saved in database...
here is the code from joomla component that i think that has to be adjusted so help guys if you can...
this is the code for checkbox...
$timetableHTML .= '<td class="timeSlot timeFree" ><input type="checkbox" name="appointment[]" value="'.$startKey.'" onclick="changeTimes(\''.$calendar->min_duration.'\',\''.$startKey.'\',\''.$endKey.'\')"/></td>';
and this is the save function in controller of the component...
function save() {
global $app;
JRequest::checkToken() or jexit( 'Invalid Token' );
$db =& JFactory::getDBO();
$row =& JTable::getInstance('appointments', 'Table');
$post = JRequest::get( 'post',4 );
if (!$row->bind( $post )) { JError::raiseError(500, $row->getError() ); }
for ($i=1;$i<=10;$i++) {
if (is_array($row->{'field'.$i})) $row->{'field'.$i} = implode('|',$row->{'field'.$i}); $row->{'field'.$i} = strip_tags($row->{'field'.$i});
}
if (!$row->check()) { JError::raiseError(500, $row->getError() ); }
if (!$row->store()) { JError::raiseError(500, $row->getError() ); }
$row->checkin();
if ($this->config->emails){
$this->notifyOwner(array($row->id));
$this->notifyAppointee(array($row->id));
}
$url = JRoute::_('index.php?option=com_jxtcappbook'.(JRequest::getInt( 'pop', 0) ? '&view=complete&tmpl=component' : ''));
$this->setRedirect($url ,JText::_( 'Termin je zakazan!'.$pop ));
}
i googled a bit and i think i need to set jrequest::get with array,am i right?
Assuming Joomla >1.6. Since you use JRequest a fair amount:
$appointments = JRequest::getVar('appointments', null, 'post', 'array');
or better yet since this will be deprecated post 3.0 you can use JInput:
$jinput = JFactory::getApplication()->input;
$appointments = $jinput->post->get('appointments', 'null', 'ARRAY');
Sanitize input and add to DB:
foreach (array_keys($appointments ) as $element) {
$myappointments[] = $db->quote($element);
}
// construct query using implode and use comma separator
$myappointments = implode(',', $myappointments );
$db =& JFactory::getDBO();
$query = $db->getQuery(true);
$query = sprintf('UPDATE $db->quoteName(#__mytable) SET $db->quote(...) WHERE $db->quote(...) IN (%s)', $myappointments );
$db->setQuery($query);
$db->query();
You get the idea...
EDIT (based on your comment):
I still don't know what you are trying to achieve. So it is hard for me to provide direction. I'll take another stab at it. I'm guessing you want to take the values that are checked from the form and put that into the database.
//this pulls out the values in an array of all the things that have been "checked" (selected in the checkbox)
$jinput = JFactory::getApplication()->input;
$appointments = $jinput->post->get('appointments', 'null', 'ARRAY');
//**This is not code you need** I just want to illustrate what you are getting.
//This is looping through the values of the checkboxes to see what you have
for($i=0; $i < count($appointments); $i++){
echo "Selected " . $appointments[$i];
}
The code I provided before shows you how to take the values and store into a DB. I can't give instructions on the DB because I don't know the DB structure.

Incorporating next/ previous in my 'foreach statement

I want to have a previous|next link on my page to change pictures.
I use a function to get relevent elements. However, I do not know what additional code is require in my function and where to place it. Also what should be in the html section.
I have looked at many pages on next/previous from 'foreach' but I cannot seem to relate to them.
Code:
function image_data($image_album_id) {
$image_album__id = (int)$image_album_id;
$args = func_get_args();
unset($args[0]);
$fields = '`'.implode('`, `', $args).'`';
$query = mysql_query("SELECT $fields FROM `album_images`
WHERE `image_album_id`=$image_album_id AND `member_id`= '1'");
$ query_result = mysql_fetch_assoc($query);
foreach ($args as $field) {
$args[$field] = $query_result[$field];
}
return $args;
}
Html Page:
Last|
Next
</div>
<?php
$image_album_id =$_GET['image_album_id'];
$image_data = image_data($image_album_id, 'album_id', 'albumname', 'ext', 'timestamp');
echo '';
?>
<td class="smallfont albumthumb2" align="center" valign="middle" >
<img alt="" class="album_cover" src="<?php echo 'images/albums/thumbs/'. $image_data['album_id']. '/'. $image_album_id. '.' .$image_data['ext'];?> " height="175px" width="175px">
</td>
Many thanks. I hope I make sense.
Thanks for the speedy response.
Since there is a lot to look at and digest I thought I would just see if it works.
Alas no.
There is a parse error: syntax error, unexpected
'<' on line
$prev_link = Previous;
The only thing I notice within that section was an extra curly bracket after 'title="$prev_name"}'
I see there is the same for the 'title="$next_name"}'
WIth reference to your specific questions.
I get to the album_viewT page when I click on a link in a previous page. This contains tiny thumbnails. The link being localhost/Testing/album_view.php?artist_id=4&image_album_id=4 as an example.
Not sure if I fully understand "order of date is by image_album_data
Yes there are almost 3,000 rows in the database.
I should also mention that album_id has been replaced by artist_id.
Should the href be changed to "album_view.php/id/...
Your question lacks some data i.e. what is the page you are visiting that produces this code (the URL that is) and how is your data sorted. For instance I can see that you are providing potentially more information using the album_viewT.php? script but that is not necessarily the one that displays the HTML that you have produced.
So after all this I will make some assumptions and hopefully that will give you the right guidance to get to the solution.
I am assuming that your visiting page is http://mysite.com/albums/id/25
I am also assuming that the order of the data is by image_album_id.
Finally I am assuming that you have data in your db and I don't need to check whether there are returned data in the template for the current image. You will need to sort that out yourself.
You will need to get the data first from the database:
function image_data($image_album_id)
{
$results = array(
'previous' => FALSE,
'current' => FALSE,
'next' => FALSE,
);
$image_album__id = (int)$image_album_id;
$args = func_get_args();
unset($args[0]);
$fields = '`'.implode('`, `', $args).'`';
// Current record
$results['current'] = get_data(
$fields,
"AND image_album_id = {$image_album_id}"
);
// Previous - no need to run this if we don't have a current
if ($results['current'])
{
// Current record
$results['previous'] = get_data(
$fields,
"AND image_album_id < {$image_album_id} " .
"LIMIT 1"
);
}
// Next - no need to run this if we don't have a current
if ($results['current'])
{
// Current record
$results['next'] = get_data(
$fields,
"AND image_album_id > {$image_album_id} " .
"LIMIT 1"
);
}
// If all went well the $results array will contain the data
// for the 3 records. If we are at the beginning or the end,
// the previous and/or next will be FALSE
return $results;
}
function get_data($fields, $where = '')
{
$return = FALSE;
// Template
$template = "SELECT %s "
. "FROM album_images "
. "WHERE member_id = 1 %s";
// Current record
$sql = sprintf($template, $fields, $where);
$query = mysql_query($sql);
$query_result = mysql_fetch_assoc($query);
// If data has been found
if ($query_result)
{
$return = $query_result;
}
return $return;
}
For your HTML page:
<?php
$image_album_id = $_GET['image_album_id'];
$image_data = image_data(
$image_album_id,
'album_id', 'albumname', 'ext', 'timestamp'
);
$prev_link = '';
$next_link = '';
if ($image_data['previous'])
{
$prev_id = $image_data['previous']['album_id'];
$prev_name = $image_data['previous']['albumname'];
$prev_link = <a href="/albums/id/{$prev_id}" title="$prev_name"}>Previous</a>";
}
if ($image_data['next'])
{
$next_id = $image_data['next']['album_id'];
$next_name = $image_data['next']['albumname'];
$next_link = <a href="/albums/id/{$next_id}" title="$next_name"}>Next</a>";
}
$curr_id = $image_data['current']['album_id'];
$curr_ext = $image_data['current']['ext'];
?>
<?php echo $prev_link; ?>|<?php echo $next_link; ?>
</div>
<td class="smallfont albumthumb2" align="center" valign="middle">
<a href="album_viewT.php?images/albums/thumbs/
<?php echo "{$curr_id}/{$image_album_id}.{$curr_ext}; ?>
<img alt="" class="album_cover"
src="images/albums/thumbs/
<?php echo "{$curr_id}/{$image_album_id}.{$curr_ext}"; ?>
height="175px"
width="175px" />
</a>
</td>
Note: I have split the line for the img and a tags in the HTML file for clarity.

Wordpress API question

How can I check if a category exists, and if exists, return the ID; if not, create the category?
Use Wordpress is_category(), get_cat_ID() and wp_create_category() method.
<?php
$CategoryName = "books";
if(is_category($CategoryName))
$categoryID = get_cat_ID($CategoryName);
else
$categoryID = wp_create_category($CategoryName);
?>
See wp_create_category().
include( "../../wordpress/wp-config.php" );
include( "../../wordpress/wp-admin/includes/taxonomy.php" );
$cat_id = wp_create_category( "TESTINGLOL" );
echo "created = {$cat_id}\n";
echo "returned = " . get_cat_ID( "TESTINGLOL" );
Output should go like:
created = 37450 returned = 37450
Note that this isn't very efficient, but, does the job.
create_category_if_not_exist($category_name, $echo = true) {
$id = wp_insert_term( $category_name, 'category');
if ( $echo ) return $id;
return $id;
}
Nice all in one function for doing the trick. $category_name would need to be the category slug though.
wp_insert_term() takes care of checking if the category already exists in the database. It will return the $id of the category if it exists and will return the $id of the newly created category if it doesn't pre-exist.

PHP/MySQL Printing Duplicate Labels

Using an addon of FPDF, I am printing labels using PHP/MySQL (http://www.fpdf.de/downloads/addons/29/). I'd like to be able to have the user select how many labels to print. For example, if the query puts out 10 records and the user wants to print 3 labels for each record, it prints them all in one set. 1,1,1,2,2,2,3,3,3...etc. Any ideas?
<?php
require_once('auth.php');
require_once('../config.php');
require_once('../connect.php');
require('pdf/PDF_Label.php');
$sql="SELECT $tbl_members.lastname, $tbl_members.firstname,
$tbl_members.username, $tbl_items.username, $tbl_items.itemname
FROM $tbl_members, $tbl_items
WHERE $tbl_members.username = $tbl_items.username";
$result=mysql_query($sql);
if(mysql_num_rows($result) == 0){
echo "Your search criteria does not return any results, please try again.";
exit();
}
$pdf = new PDF_Label("5160");
$pdf->AddPage();
// Print labels
while($rows=mysql_fetch_array($result)){
$name = $rows['lastname'].', '.$rows['firstname';
$item= $rows['itemname'];
$text = sprintf(" * %s *\n %s\n", $name, $item);
$pdf->Add_Label($text);
}
$pdf->Output('labels.pdf', 'D');
?>
Assuming that a variable like $copies is an integer of how many copies they want made, I would make the following modification:
// Print labels
while( $row = mysql_fetch_array( $result ) ){
// Run Once for Each Result
$name = $row['lastname'].', '.$row['firstname'];
$item = $row['itemname'];
$text = sprintf(" * %s *\n %s\n", $name, $item);
if( isset( $copies ) ) {
// The Copies Variable exists
for( $i=0 ; $i<$copies ; $i++ ) {
// Run X times - Once for each Copy
$pdf->Add_Label($text);
}
} else {
// The Copies Variable does not exist - Assume 1 Copy
$pdf->Add_Label($text);
}
}
This should provide the required functionality.

Categories