Birchpress – How Do I Export Client Appointments?

As of 2015, from what i’ve read on forums and the Birchpress documentation, you can’t — as of a few minutes ago, i have at least something working!

This is just a PHP script that you can put in a hook or whatever – but in my scenario I’m just going to the URL example.com/services/exportAppointments.php

First we want to include wordpress functionality in our service: (mine’s in a folder i made called “services”, so i need to go up a directory to the be in the root, thus the ‘../’)

<?php 
include '../wp-load.php'; 
?>

We’ll need two functions, one to find an appointment and one to find a client by an ID:

<?php
/***********************************
  Query Single Appointment Details
***********************************/ 
function getAppointment($postID){
  query_posts(array( 
    'post_type' => 'birs_appointment',
    'p' => $postID
  ));  
  while (have_posts()) : the_post(); 
    $data = get_post_meta(get_the_ID()); 
  endwhile;
  wp_reset_query();
  return $data;
}
?>
<?php
/***********************************
  Query Single Client Details
***********************************/ 
function getClient($postID){
  query_posts(array( 
    'post_type' => 'birs_client',
    'p' => $postID
  ));  
  while (have_posts()) : the_post(); 
    $data = get_post_meta(get_the_ID()); 
  endwhile;
  wp_reset_query();
  return $data;
}
?>

The post type that links these together is called “birs_appointment1on1”, so getting a query of those (you can apply your own filters here) will give me the list of all the appointments, which from there I can get the relevant info of the various clients and appointments. There may be a more sleek way to do this so you don’t re-query those, but this is just a quickie. (please note, i am using the client Zipcode as a zipcode for their private practice, and i create a custom field for their practice name, so there’s an example of custom data in there too!)

<?php
/*****************************************
  Query the Various Appointments
*****************************************/ 
$birchpress_appointments = query_posts(array( 
  'post_type' => 'birs_appointment1on1', 
  'showposts' => -1
)); 
foreach($birchpress_appointments as $birchpress_appointment): 
  $birchID = $birchpress_appointment->ID;
  $data = get_post_meta($birchID); 

  //CLIENT
  $clientID = $data['_birs_client_id'][0];
  $client = getClient($clientID);
  //APPOINTMENT
  $appointmentID = $data['_birs_appointment_id'][0];
  $appointment = getAppointment($appointmentID);
endforeach;
?>

So, let’s put it all together and export the data as a csv – hopefully this provides a good starting point for anyone that wants to take the last query and apply meta filters to the _birs_appointment_id and _birs_client_id fields

<?php 
include '../wp-load.php'; 

//OUTPUT HEADERS - makes browser download a CSV
header('Content-type: text/csv');
header('Content-Disposition: attachment; filename="appointments.csv"');
header('Pragma: no-cache');
header('Expires: 0');
$file = fopen('php://output', 'w');

// COLUMN HEADERS
fputcsv($file, array(
  'First Name', 
  'Last Name', 
  'Email', 
  'Phone', 
  'Practice Name', 
  'Practice Zip', 
  "Appointment"
));
$csvdata = array();

/*****************************************
  Query the Various Appointments
*****************************************/ 
$birchpress_appointments = query_posts(array( 
  'post_type' => 'birs_appointment1on1', //birs_appointment
  'showposts' => -1
)); 
foreach($birchpress_appointments as $birchpress_appointment): 
  $birchID = $birchpress_appointment->ID;
  $data = get_post_meta($birchID); 

  //CLIENT DATA
  $clientID = $data['_birs_client_id'][0];
  $client = getClient($clientID);
  $fname = $client['_birs_client_name_first'][0];
  $lname = $client['_birs_client_name_last'][0];
  $email = $client['_birs_client_email'][0];
  $phone = $client['_birs_client_phone'][0];
  $practiceName = $client['_birs_field_6'][0];
  $practiceZip = $client['_birs_client_zip'][0];

  //APPOINTMENT DATA
  $appointmentID = $data['_birs_appointment_id'][0];
  $appointment = getAppointment($appointmentID);
  $timestamp = $appointment['_birs_appointment_timestamp'][0];
  
  // COLUMN ROWS -- match COLUMN HEADERS array structure
  $csvdata[] = array(
    $fname,
    $lname,
    $email,
    $phone,
    $practiceName,
    $practiceZip,
    date('Y-m-d H:i:s', $timestamp)
  );

endforeach;
wp_reset_query();

// output each row of the data
foreach ($csvdata as $row){
  fputcsv($file, $row);
}
exit();


/***********************************
  Query Single Appointment Details
***********************************/ 
function getAppointment($postID){
  query_posts(array( 
    'post_type' => 'birs_appointment',
    'p' => $postID
  ));  
  while (have_posts()) : the_post(); 
    $data = get_post_meta(get_the_ID()); 
  endwhile;
  wp_reset_query();
  return $data;
}


/***********************************
  Query Single Client Details
***********************************/ 
function getClient($postID){
  query_posts(array( 
    'post_type' => 'birs_client',
    'p' => $postID
  ));  
  while (have_posts()) : the_post(); 
    $data = get_post_meta(get_the_ID()); 
  endwhile;
  wp_reset_query();
  return $data;
}

?>

How do I get a page’s current URL in Twig for Drupal 8?

Having access to a site’s URL in your templates can come in handy for many different use cases, but one of the more common scenarios might be for those of you building multi-sites.

Let’s say you’re building a site with various domain names and you want to be able to conditionally change some content or functionality for each domain in your Twig templates. You can get the current URL and parse it for a substring like this:

{% set site_url = url("<current>") %}
{% if 'example-one.com' in site_url|render|render %}
     {# example-one.com content #}
{% elseif 'example-two.com' in site_url|render|render %}
     {# example-two.com content #}
{% endif %}

Visual Composer: vc_map field examples

There’s a few things missing to the documentation for Visual composer, like samples of how to use each field type.  Some of these are probably pretty intuitive, but we figured we’d make some example for each as more of a library of snippets to pick for the vc_map function. Sometimes just an example of something that works for a type is all you need to feel more confident — Enjoy!  [VC Documentation]

textarea_html
Text area with default WordPress WYSIWYG Editor. Important: only one html textarea is permitted per shortcode and it should have “content” as a param_name

array(
  "type" => "textarea_html",
  "class" => "",
  "heading" => __( "Field Label", "my-text-domain" ),
  "param_name" => "field_name",
  "value" => '', 
  "description" => __( "Enter description.", "my-text-domain" )
)

textfield/textarea
Simple input / textarea field

array(
  "type" => "textfield",
  "class" => "",
  "heading" => __( "Field Label", "my-text-domain" ),
  "param_name" => "field_name",
  "value" => __( "", "my-text-domain" ),
  "description" => __( "Enter description.", "my-text-domain" )
)
array(
  "type" => "textarea",
  "class" => "",
  "heading" => __( "Field Label", "my-text-domain" ),
  "param_name" => "field_name",
  "value" => __( "", "my-text-domain" ),
  "description" => __( "Enter description.", "my-text-domain" )
)

dropdown
Dropdown input field with set of available options. Array containing the drop down values (either should be a normal array, or an associative array)

array(
  'type' => 'dropdown',
  'heading' => __( 'Field Label',  "my-text-domain" ),
  'param_name' => 'field_name',
  'value' => array(
    __( 'Option 1 Label',  "my-text-domain"  ) => 'option1value',
    __( 'Option 2 Label',  "my-text-domain"  ) => 'option2value',
    __( 'Option 3 Label',  "my-text-domain"  ) => 'option3value',
  ),
  "description" => __( "Enter description.", "my-text-domain" )
)

attach_imageattach_images
Single image selection/Multiple images selection

array(
  "type" => "attach_image",
  "class" => "",
  "heading" => __( "Field Label", "my-text-domain" ),
  "param_name" => "field_name",
  "value" => '',
  "description" => __( "Enter description.", "my-text-domain" )
)
array(
  "type" => "attach_images",
  "class" => "",
  "heading" => __( "Field Label", "my-text-domain" ),
  "param_name" => "field_name",
  "value" => '',
  "description" => __( "Enter description.", "my-text-domain" )
)

posttypes
Checkboxes with available post types (automatically finds all post types)

array(
  "type" => "posttypes",
  "class" => "",
  "heading" => __( "Field Label", "my-text-domain" ),
  "param_name" => "field_name",
  "value" => __( "", "my-text-domain" ),
  "description" => __( "Enter description.", "my-text-domain" )
)	

colorpicker
Color picker

array(
  "type" => "colorpicker",
  "class" => "",
  "heading" => __( "Field Label", "my-text-domain" ),
  "param_name" => "field_name",
  "value" => '', 
  "description" => __( "Enter description.", "my-text-domain" )
)

exploded_textarea
Text area, where each line will be imploded with comma (,)

array(
  "type" => "exploded_textarea",
  "class" => "",
  "heading" => __( "Field Label", "my-text-domain" ),
  "param_name" => "field_name",
  "value" => '', 
  "description" => __( "Enter description.", "my-text-domain" )
)

widgetised_sidebars
Dropdown element with set of available widget regions, that are registered in the active wp theme

array(
  "type" => "widgetised_sidebars",
  "class" => "",
  "heading" => __( "Field Label", "my-text-domain" ),
  "param_name" => "field_name",
  "value" => '', 
  "description" => __( "Enter description.", "my-text-domain" )
)

textarea_raw_html
Text area, its content will be coded into base64 (this allows you to store raw js or raw html code)

array(
  "type" => "textarea_raw_html",
  "class" => "",
  "heading" => __( "Field Label", "my-text-domain" ),
  "param_name" => "field_name",
  "value" => '', 
  "description" => __( "Enter description.", "my-text-domain" )
)

vc_link
Link selection. Then in shortcodes html output, use $href = vc_build_link( $href ); to parse link attribute

array(
  "type" => "vc_link",
  "class" => "",
  "heading" => __( "Field Label", "my-text-domain" ),
  "param_name" => "field_name",
  "value" => '', 
  "description" => __( "Enter description.", "my-text-domain" )
)

checkbox
Creates checkboxes, can have 1 or multiple checkboxes within one attribute

array(
  "type" => "checkbox",
  "class" => "",
  "heading" => __( "Field Label", "my-text-domain" ),
  "param_name" => "field_name",
  "value" => __( "", "my-text-domain" ),
  "description" => __( "Enter description.", "my-text-domain" )
)

loop
Loop builder. Lets your users to construct loop which can later be used during the shortcode’s output

array(
  "type" => "loop",
  "class" => "",
  "heading" => __( "Field Label", "my-text-domain" ),
  "param_name" => "field_name",
  "value" => '', 
  "description" => __( "Enter description.", "my-text-domain" )
)

css
Basic CSS style editor for your content element. Check “Add “Design Options” Tab with CSS Editor to Your Element” page for more details

array(
  "type" => "css",
  "class" => "",
  "heading" => __( "Field Label", "my-text-domain" ),
  "param_name" => "field_name",
  "value" => '', 
  "description" => __( "Enter description.", "my-text-domain" )
)

… attribute types can be extended with new custom types.
Create Your Own 

How do i get all the taxonomies of a node to render in Drupal7?

After following a tutorial for getting the taxonomy terms of a node, I found that I still didn’t have all the pieces of the puzzle. Doing a foreach over $tags = $node->field_tags; would just give a disappointing one result with those nodes had more than one taxonomy assigned to it. (The other 3 were being lost in the code abyss!)

This was solved by digging a little deeper into the object that was return:

<div class="tagsList views-field-field-tags">
	<? $tags = $node->field_tags['und']; ?>                            
	Tags: <? $count = 0; 
	foreach($tags as $tag){ 
	if($count > 0){echo ", ";}
	echo '<a href="'.taxonomy_term_path($tag['taxonomy_term']).'">'.$tag['taxonomy_term']->name.'</a>'; 
	$count++;
	} ?>
</div>

Turns out i had to go one layer deeper to loop the tags object as the language code is undefined. SO now my taxonomies are working great on the node.tpl.php for that feed.

Source

PHP Get Content Between Characters

Recently, I needed to get the content of an email address formatted as “Tim Barsness ” as just the email address “email@address.com”. I wrote a function to do so. It ended up being pretty straight forward.

function getContentBetween($content, $lead, $trail)
{
	//Gets content after last occurrence of $lead as $between_split[count($from_split)]
	$between_split = split($lead, $content);
	//Gets content before $trail as $between_split[0]
	$between_split = split($trail, $between_split[count($from_split)]);
	return $between_split[0];
}

Which can be used as follows:

$email = 'Tim Barsness <email@address.com>';

echo getContentBetween($email, '<', '>');  //returns email@address.com

str_ireplace

On a project I had to do a php str_replace on a string but I ran into a problem as the string is user controlled. This could be upper case or lower so we needed something more. Without getting into things as complex as preg_replace I found str_ireplace. I can’t believe I hadn’t noticed this before. It’s the same as str_replace but is not case sensitive. Problem solved.