Archive for the ‘PHP’ Category

Oracle Service Cloud RightNowCX External Events / Custom Process: Curl a service on Save or Update

Thursday, February 16th, 2017
/*
* CPMObjectEventHandler: updateContact
* Package: OracleServiceCloud
* Objects: Contact
* Actions: Create, Update
* Version: 1.3
*/

use \RightNow\CPM\v1 as RNCPM;
use \RightNow\Connect\v1_3 as RNCPHP;

load_curl();

class updateContact implements RNCPM\ObjectEventHandler {

/**
* Apply CPM logic to object.
* @param int $runMode
* @param int $action
* @param object $contact
* @param int $cycle
*/
public static function apply($run_mode, $action, $contact, $n_cycles) {

if ($n_cycles != 0) return;

try {

$contact->CustomFields->c->contact_field_being_checked = new RNCPHP\NamedIDLabel();
$contact->CustomFields->c->contact_field_being_checked->ID = 2192; // Unregistered CPM
$header[] = "Content-Type: application/x-www-form-urlencoded";
$service_endpoint = 'http://INTERFACE-URL/cgi-bin/nikeagent.cfg/php/custom/scriptName.php?email=';

$noEmail = true;

foreach ($contact->Emails as $email) {
if ($email) {
$noEmail = false; // found an email

$ch = curl_init();
curl_setopt_array($ch, array(
CURLOPT_URL => $service_endpoint . $email->Address,
CURLOPT_HEADER => 0,
CURLOPT_HTTPHEADER => $header,
CURLOPT_FOLLOWLOCATION => 1,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_SSL_VERIFYPEER => 0,
CURLOPT_SSL_VERIFYHOST => 0
));
$resp = curl_exec($ch);

if ($resp !== false) {
$respObj = json_decode($resp, true);
$regUserString = $respObj['contact_field_being_checked']; // 1 or empty, is boolean
if ($regUserString == 1) {
$contact->CustomFields->c->contact_field_being_checked->ID = 2189; // Registered CPM
}else{
}
}
curl_close($ch);
}
}

$contact->save(RNCPHP\RNObject::SuppressAll);
} catch (\Exception $e) {
throw $e;
}

return;
}
}

class updateContact_TestHarness implements RNCPM\ObjectEventHandler_TestHarness {
static $test_contact = null;

public static function setup() {
// TODO: Pass array of contacts
// Should pass an array of contacts with different
// emails and different orders of registered emails

// We want to create contacts on the fly, but
// you can't duplicate emails, so we should probably check
// if the email exists, and delete it - perhaps have a set test
// contact
try {
$contact = new RNCPHP\Contact;
$contact->Emails = new RNCPHP\EmailArray();
$contact->Emails[0] = new RNCPHP\Email();
$contact->Emails[0]->AddressType = new RNCPHP\NamedIDOptList();
$contact->Emails[0]->AddressType->LookupName = "Email - Primary";
$contact->Emails[0]->Address = "somebody@fastmail.jp";
$contact->Emails[0]->Invalid = false;
$contact->CRMModules = new RNCPHP\CRMModules();
$contact->CRMModules->Service = 1;
$contact->save(RNCPHP\RNObject::SuppressAll);

static::$test_contact = $contact;
} catch (\Exception $e) {
echo $e->getMessage();
}

return;
}

public static function fetchObject($action, $object_type) {
// Returned object is passed to apply()
return (static::$test_contact);
}

public static function validate($action, $object) {
if (RNCPM\ActionCreate == $action) {
if (assert($object->CustomFields->c->contact_field_being_checked->ID == 2189)) {
echo "Create test passed - " . $object->Emails[0]->Address . "\n";
return true;
} else {
echo "Create test FAILED - " . $object->Emails[0]->Address . "\n";
}
} elseif (RNCPM\ActionUpdate == $action) {
if (assert($object->CustomFields->c->contact_field_being_checked->ID == 2189)) {
echo "Update test passed - " . $object->Emails[0]->Address . "\n";
return true;
} else {
echo "Update test FAILED - " . $object->Emails[0]->Address . "\n";
}
} else {
echo "Invalid action";
}
}

public static function cleanup() {
// Delete temporary test contact
$contact = static::$test_contact;
$contact->destroy();

static::$test_contact = null;
}
}

Oracle Service Cloud RightNowCX Event subscribe Notes

Tuesday, August 30th, 2016

RightNow.Event.subscribe("evt_chatCobrowseAcceptResponse",function(e, f){console.log(e,f);},null);
RightNow.Event.subscribe("evt_chatCobrowseStatusResponse",function(e, f){console.log(e,f);},null);
RightNow.Event.subscribe("evt_fileUploadUpdateResponse",function(e, f){console.log(e,f);},null);
RightNow.Event.subscribe("evt_chatNotifyFattachUpdateResponse",function(e, f){console.log(e,f);},null);
RightNow.Event.subscribe("evt_chatPostResponse",function(e, f){console.log(e,f);},null);
RightNow.Event.subscribe("evt_chatEngagementParticipantAddedResponse",function(e, f){console.log(e,f);},null);
RightNow.Event.subscribe("evt_chatEngagementParticipantRemovedResponse",function(e, f){console.log(e,f);},null);
RightNow.Event.subscribe("evt_chatEngagementConcludedResponse",function(e, f){console.log(e,f);},null);
RightNow.Event.subscribe("evt_chatCobrowseInvitationResponse",function(e, f){console.log(e,f);},null);
RightNow.Event.subscribe("evt_chatReconnectUpdateResponse",function(e, f){console.log(e,f);},null);
RightNow.Event.subscribe("evt_chatAgentAbsentUpdateResponse",function(e, f){console.log(e,f);},null);
RightNow.Event.subscribe("evt_chatAgentStatusChangeResponse",function(e, f){console.log(e,f);},null);
RightNow.Event.subscribe("evt_chatPostCompletion",function(e, f){console.log(e,f);},null);
RightNow.Event.subscribe("evt_chatEventBusInitializedResponse",function(e, f){console.log(e,f);},null);
RightNow.Event.subscribe("evt_chatConnectResponse",function(e, f){console.log(e,f);},null);
RightNow.Event.subscribe("evt_chatFetchUpdateResponse",function(e, f){console.log(e,f);},null);
RightNow.Event.subscribe("evt_chatStateChangeResponse",function(e, f){console.log(e,f);},null);
RightNow.Event.subscribe("evt_chatSetParametersResponse",function(e, f){console.log(e,f);},null);
RightNow.Event.subscribe("evt_chatValidateParametersResponse",function(e, f){console.log(e,f);},null);
RightNow.Event.subscribe("evt_chatCheckAnonymousResponse",function(e, f){console.log(e,f);},null);

example:

RightNow.Event.subscribe("evt_chatStateChangeResponse",function(e,f){
if(f[0].data.currentState && f[0].data.currentState == 2) {
window.chatID = RightNow.Chat.Controller.ChatCommunicationsController._engagementID;
}
},null);

Oracle Service Cloud RightNowCX Configuration for Developer Chatting with Self

Tuesday, August 30th, 2016

-> Chat starts

-> Triggers Rules evaluation

-> Rule matches regex on email submitted

-> Routes the chat to a particular queue

-> Queue is assigned to a profile

-> Profile is assigned to dev

Now you can submit a chat request via the page/UI, and receive it via the console, or let it sit to develop “waiting”/unconnected experience!

Oracle Service Cloud RightnowCX Custom Controller: Lookup Contact, Create Incident

Tuesday, August 30th, 2016

<?php

namespace Custom\Controllers;

/************* Agent Authentication ***************/
require_once( get_cfg_var("doc_root")."/ConnectPHP/Connect_init.php" );
initConnectAPI();

use RightNow\Connect\v1_2 as RNCPHP;

class GSChatIncident extends \RightNow\Controllers\Base
{

function __construct()
{
parent::__construct();
}

public function createContactIncident() {

try{
\RightNow\Libraries\AbuseDetection::check();

//$incident->SiteInterface = new RNCPHP\NamedIDLabel();
//$incident->SiteInterface->ID = 111;

$email = $_POST['email'];
$cID = (int)$_POST['countryID'];
$languageID = (int)$_POST['langID'];

$CI = &get_instance();
$contactmodelobj=$CI->load->model('standard/Contact_model');

$found = $this->Contact_model->lookupContactByEmail($email, null, null)->result;

if($found != null && is_int($found) && $found != false){
$creatingContact = $found;
} else {
$creatingContact = 1;
}

$incident = new RNCPHP\Incident();
$incident->Subject = "Chat cancelled";
$incident->CustomFields->c->system_source->ID = 2156;
$incident->CustomFields->c->country = new RNCPHP\NamedIDLabel();
$incident->CustomFields->c->country = $cID;
$incident->Language = $languageID;
$incident->PrimaryContact = RNCPHP\Contact::fetch($creatingContact); //Required field to create an incident through connect PHP
$incident->save(RNCPHP\RNObject::SuppressAll);
}

catch (Exception $err ){
echo $err->getMessage();
}
}
}
?>

Oracle Service Cloud RightNow CX PHP Connect API write to Custom Business Object example Custom Controller

Tuesday, August 30th, 2016

url: /cc/GSChatLog/createChatLog


<?php

namespace Custom\Controllers;

/************* Agent Authentication ***************/
require_once( get_cfg_var("doc_root")."/ConnectPHP/Connect_init.php" );
initConnectAPI();
use RightNow\Connect\v1_2 as RNCPHP;

class GSChatLog extends \RightNow\Controllers\Base
{

function __construct()
{
parent::__construct();
}

public function createChatLog() {

try{
\RightNow\Libraries\AbuseDetection::check();

$email = $_POST['email'];
$cID = (int)$_POST['countryID'];
$languageID = (int)$_POST['langID'];
$name = $_POST['name'];
$referrerUrl = $_POST['referrerUrl'];
$siteID = $_POST["siteID"];
$platformID = $_POST["platformID"];
$chatStatus = $_POST["chatStatus"];
$chatID = $_POST["chatID"];
$lob = strtoupper($_POST["lob"]);

$log = new RNCPHP\ContactUs\chat_log();
$log->chat_id = $chatID;
$log->chat_log_status = $chatStatus;
$log->site_id = $siteID;
$log->chat_group = 2156;
$log->referring_url = $referrerUrl;
$log->interface = $platformID;
$log->email_address = $email;
$log->name = $name;
$log->language_id = $languageID;
$log->country_id = $cID;
$log->lob_id = $lob;
$log->save();

catch (Exception $err ){
echo $err->getMessage();
}
}
}
?>

Oracle Service Cloud RightNow CX PHP Connect API Analytics Report example

Tuesday, August 30th, 2016

$report_id = ..74..;
$report = RNCPHP\AnalyticsReport::fetch($report_id);

$report_filter = new RNCPHP\AnalyticsReportSearchFilter;
$report_filter->Name = 'chats.email';
$report_filter->Values = array($email);
$filters = new RNCPHP\AnalyticsReportSearchFilterArray;
$filters[] = $report_filter;

$report_result = $report->run(0,$filters);

while($reportRow = $report_result->next())
{
print_r($reportRow);
$chatID = (int)$reportRow['chat_id'];
}

Google maps, mySQL locations, PHP service

Wednesday, May 4th, 2016

HTML:

<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
    <link rel="stylesheet" href="dealers.css">
</head>
    <body>
        <div class="row mapSection">
            <div class="col-xs-12">

                <div id="map"></div>
                <div id="panel">
                    <div id="entryRow">
                        <div><select id="locationSelect" style="width:100%;visibility:hidden"></select></div>
                        <input type="text" id="addressInput" />
                        <select id="radiusSelect">
                            <option value="5" selected>5 miles</option>
                            <option value="25" selected>25 miles</option>
                            <option value="100">100 miles</option>
                            <option value="200">200 miles</option>
                            <option value="500">500 miles</option>
                        </select>
                        <input type="text" id="find" value="Search"/>
                        <input type="button" id="refresh" value="redo Search"/>
                    </div>
                    <ul class="resultDealers">
                    </ul>
                </div>

            </div>
        </div>

        <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script>
        <script src="https://maps.googleapis.com/maps/api/js?key=***YOUR*KEY*HERE***" type="text/javascript"></script>
        <script type="text/javascript" src="Maps.js"></script>
    </body>
</html>

CSS:

body {
  font-family: sans-serif;
  margin: 0px;
  padding: 0px;
}
#map,
#panel {
  height: 500px;
  float: left;
}
#map {
  width: 60%;
}
#entryRow {
  margin: 0 0 0 15px;
}
#panel {
  width: 40%;
}
.resultDealers {
  padding: 0;
  margin: 15px;
  overflow: scroll;
  height: 420px;
}
.resultDealers li {
  list-style-type: none;
  border-left: 1px solid;
  border-top: 1px solid;
  border-right: 1px solid;
  padding: 10px;
}
.resultDealers li:last-child {
  border-bottom: 1px solid;
}
.highlightDealer {
  background: #E8E8E8;
}
.markerBox {
  cursor: pointer;
}
.markerBox:hover {
  background: #E3F4F9;
}
#panel .feature-filter label {
  width: 130px;
}
p.attribution,
p.attribution a {
  color: #666;
}
#find {
  background: #DEDCDC;
  border: 1px solid gray;
  width: 65px;
  padding: 2px;
  text-align: center;
  font-weight: bold;
  cursor: pointer;
  margin-left: 15px;
}
#find:hover {
  background: #F9F4F4;
}
#radiusSelect {
  margin-left: 15px;
}
#addressInput {
  float: left;
  margin-left: 5px;
  padding-left: 10px;
  width: 65px;
}
#locationSelect {
  margin: 10px 5px;
  width: 95% !important;
}

JavaScript:

/* ---------  Start Maps.js  --------- */

Maps Module
//Usage: Maps.init();

Maps = (function ( window, google ) {

	var map,
		markers = [],
		infoWindow,
		locationSelect;

	var load = function load () {
			map = new google.maps.Map(document.getElementById("map"), {
				center: new google.maps.LatLng(40, -100),
				zoom: 4,
				mapTypeId: 'roadmap',
				// scrollWheel: false,
				// zoomControl: false,
				streetViewControl: false,
				rotateControl: false,
				fullscreenControl: false,
				navigationControl: false,
				scaleControl: false,
				// draggable: false,
				mapTypeControl: false,
				mapTypeControlOptions: {style: google.maps.MapTypeControlStyle.DROPDOWN_MENU}
		});
		infoWindow = new google.maps.InfoWindow();

		locationSelect = document.getElementById("locationSelect");
		locationSelect.onchange = function() {
			var markerNum = locationSelect.options[locationSelect.selectedIndex].value;
			if (markerNum != "none"){
				google.maps.event.trigger(markers[markerNum], 'click');
			}
		};

		refreshMap();

		google.maps.event.addListener(map, 'zoom_changed', function() {
			//$('#radiusSelect option:selected').next().attr('selected', 'selected');
			//console.log(map.getCenter());
			//searchLocationsNear (map.getCenter());
		});

	}

	var bindInfoWindow = function bindInfoWindow ( marker, map, infoWindow, html ) {
      google.maps.event.addListener(marker, 'click', function() {
        infoWindow.setContent(html);
        infoWindow.open(map, marker);
      });
    }

    var refreshMap = function refreshMap () {
    	if(navigator.geolocation) {
			navigator.geolocation.getCurrentPosition(function(position) {

				var latLng = new google.maps.LatLng(position.coords.latitude,position.coords.longitude);

				var geocoder = new google.maps.Geocoder();

				geocoder.geocode({ 'latLng': latLng}, function (results, status) {
					if (status == google.maps.GeocoderStatus.OK) {

						for ( var j = 0; j < results[0].address_components.length; j++ ) {
							for ( var k = 0; k < results[0].address_components[j].types.length; k++ ) {
								if ( results[0].address_components[j].types[k] == "postal_code" ) {
									zipcode = results[0].address_components[j].short_name;
								}
							}
						}

						document.getElementById("addressInput").value = zipcode;
						searchLocations();
					} else {
						console.log("Geocoding failed: " + status);
					}
				});
			});
		}
	}

	var downloadUrl = function downloadUrl ( url, callback ) {
		var request = window.ActiveXObject ? new ActiveXObject('Microsoft.XMLHTTP') : new XMLHttpRequest;
		request.onreadystatechange = function() {
			if ( request.readyState == 4 ) {
				request.onreadystatechange = doNothing;
				callback(request.responseText, request.status);
			}
		};

		request.open('GET', url, true);
		request.send(null);
	}

	var searchLocations = function searchLocations () {
		var address = document.getElementById("addressInput").value;
		var geocoder = new google.maps.Geocoder();
		geocoder.geocode({address: address}, function(results, status) {
			if (status == google.maps.GeocoderStatus.OK) {
	  			searchLocationsNear(results[0].geometry.location);
			} else {
	  			alert(address + ' not found');
			}
		});
	}

	var clearLocations = function clearLocations() {
		infoWindow.close();
		for (var i = 0; i < markers.length; i++) {
			markers[i].setMap(null);
		}
		markers.length = 0;

		locationSelect.innerHTML = "";
		var option = document.createElement("option");
		option.value = "none";
		option.innerHTML = "See all results:";
		locationSelect.appendChild(option);
	}

	var searchLocationsNear = function searchLocationsNear ( center ) {
		clearLocations();

		var radius = document.getElementById('radiusSelect').value;
		var searchUrl = '/dealers.php?lat=' + center.lat() + '&lng=' +  center.lng() + '&radius=' + radius;
		downloadUrl( searchUrl, function(data) {
			var xml = parseXml(data);
			var markerNodes = xml.documentElement.getElementsByTagName("marker");
			var bounds = new google.maps.LatLngBounds();
			for (var i = 0; i < markerNodes.length; i++) {
				var id = markerNodes[i].getAttribute("id");
				var name = markerNodes[i].getAttribute("name");
				var address = markerNodes[i].getAttribute("address");
				var city = markerNodes[i].getAttribute("city");
				var state = markerNodes[i].getAttribute("state");
				var zip = markerNodes[i].getAttribute("zip");
				var url = markerNodes[i].getAttribute("url");
				var email = markerNodes[i].getAttribute("email");
				var distance = parseFloat(markerNodes[i].getAttribute("distance"));
				var latlng = new google.maps.LatLng(
					parseFloat(markerNodes[i].getAttribute("lat")),
					parseFloat(markerNodes[i].getAttribute("lng")));

				createOption(name, distance, i);
				createMarker(id, latlng, name, address, city, state, zip, url, email);
				bounds.extend(latlng);
			}
			map.fitBounds(bounds);
			locationSelect.style.visibility = "visible";
			locationSelect.onchange = function() {
			 var markerNum = locationSelect.options[locationSelect.selectedIndex].value;
			 google.maps.event.trigger(markers[markerNum], 'click');
			};
		});
	}

	var createMarker = function createMarker ( id, latlng, name, address, city, state, zip, url, email ) {
		var html = "<div class='marker-" + id + "'><b>" + name + "</b> <br/>" + address +  "<br/>" + city + " " + state + ", " + zip + "<br />" + url + "<br /><a href='mailto:" + email + "'>" + email + "</a></div>";
		var marker = new google.maps.Marker({
			map: map,
			position: latlng
		});
		google.maps.event.addListener(marker, 'click', function() {
			//infoWindow.setContent(html);
			//infoWindow.open(map, marker);
			$("li[class*='marker-']").removeClass('highlightDealer');
			$("li.marker-" + id).addClass('highlightDealer');
			window.location.href = "#marker-"+ id;
			window.scrollTo(0, 0);

			map.setZoom(16);
			map.setCenter(marker.getPosition());
		});
		markers.push(marker);

		$("#panel ul").append("<li class='markerBox marker-" + id + "'><a name='marker-" + id + "'></a><b>" + name + "</b><br/>" + address +  "<br/>" + city + " " + state + ", " + zip + "<br />" + url + "<br /><a href='mailto:" + email + "'>" + email + "</a></li>");
		$('.marker-' + id).on('click', function() {
			$("li[class*='marker-']").removeClass('highlightDealer');
			$("li.marker-" + id).addClass('highlightDealer');
			map.setZoom(16);
			map.setCenter(marker.getPosition());
		});
	}

	var createOption = function createOption ( name, distance, num ) {
		var option = document.createElement("option");
		option.value = num;
		option.innerHTML = name + "(" + distance.toFixed(1) + ")";
		locationSelect.appendChild(option);
	}

	var parseXml = function parseXml(str) {
		if (window.ActiveXObject) {
			var doc = new ActiveXObject('Microsoft.XMLDOM');
			doc.loadXML(str);
			return doc;
		} else if (window.DOMParser) {
			return (new DOMParser).parseFromString(str, 'text/xml');
		}
	}

    function doNothing() {}

	$('#find').on('click', function() {
		$('#panel ul').empty();
		searchLocations();
	});
	$('#addressInput').on('click', function () {
		$(this).val('');
	});
	$('#radiusSelect').on('change', function () {
		$('#panel ul').empty();
		searchLocations();
	});
	$('#refresh').on('click', function () {
		var bounds = map.getBounds();
		var ne = bounds.getNorthEast(); // LatLng of the north-east corner
		var sw = bounds.getSouthWest(); // LatLng of the south-west corder

		var nw = new google.maps.LatLng(ne.lat(), sw.lng());
		var se = new google.maps.LatLng(sw.lat(), ne.lng());
		console.log('nw: ' + nw);
		console.log('se: ' + se);
		//searchLocationsNear();
		//searchLocations();
	});

	return {
		load: load
	}

})( window, google );

$(function(){
    loadModules.start();
})

var loadModules = loadModules || {};
loadModules.start = function(){
    // Maps module init
    Maps.load();
};
/* ---------  End Maps.js --------- */

PHP:

<?php
    header("Access-Control-Allow-Origin: *");
    $servername = "***Your*DB*URL***";
    $username = "***Your*DB*USERNAME***";
    $password = "***Your*DB*PASS***";
    $dbname = "***Your*DB*NAME***";

    // Get parameters from URL
    $center_lat = $_GET["lat"];
    $center_lng = $_GET["lng"];
    $radius = $_GET["radius"];

    // Start XML file, create parent node
    $dom = new DOMDocument("1.0");
    $node = $dom->createElement("markers");
    $parnode = $dom->appendChild($node);

    // Opens a connection to a mySQL server
    $connection=mysql_connect ($servername, $username, $password);
    if (!$connection) {
      die("Not connected : " . mysql_error());
    }

    // Set the active mySQL database
    $db_selected = mysql_select_db($dbname, $connection);
    if (!$db_selected) {
      die ("Can\'t use db : " . mysql_error());
    }

    // Search the rows in the markers table
    $query = sprintf("SELECT id, name, address, city, state, zip, url, email, lat, lng, ( 3959 * acos( cos( radians('%s') ) * cos( radians( lat ) ) * cos( radians( lng ) - radians('%s') ) + sin( radians('%s') ) * sin( radians( lat ) ) ) ) AS distance FROM dealers HAVING distance < '%s' ORDER BY distance LIMIT 0 , 20",
      mysql_real_escape_string($center_lat),
      mysql_real_escape_string($center_lng),
      mysql_real_escape_string($center_lat),
      mysql_real_escape_string($radius));
    $result = mysql_query($query);

    $result = mysql_query($query);
    if (!$result) {
      die("Invalid query: " . mysql_error());
    }

    header("Content-type: text/xml");

    // Iterate through the rows, adding XML nodes for each
    while ($row = @mysql_fetch_assoc($result)){
        $node = $dom->createElement("marker");
        $newnode = $parnode->appendChild($node);
        $newnode->setAttribute("id", $row['id']);
        $newnode->setAttribute("name", $row['name']);
        $newnode->setAttribute("address", $row['address']);
        $newnode->setAttribute("city", $row['city']);
        $newnode->setAttribute("state", $row['state']);
        $newnode->setAttribute("zip", $row['zip']);
        $newnode->setAttribute("url", $row['url']);
        $newnode->setAttribute("email", $row['email']);
        $newnode->setAttribute("lat", $row['lat']);
        $newnode->setAttribute("lng", $row['lng']);
        $newnode->setAttribute("distance", $row['distance']);
    }

    echo $dom->saveXML();

?>

WordPress Powerpress Youtube loop to show all posts with thumbnail

Tuesday, December 8th, 2015

Add a loop to index.php (Main Index Template) to show all the blog’s posts/youtube videos with thumbnails below the homepage most recent single post.

<?php
/* added loop to return all wordpress posts */
	$rPosts = new WP_Query();
    	$rPosts->query('showposts=-1');
    	while ($rPosts->have_posts()) : $rPosts->the_post();

/* retrieve custom 'enclosure' value, which contains the Youtube embed code, from each post */	
		$enclosure = get_post_custom_values('enclosure');

/* don't render it immediately so that we can see what we're getting back */
		$enclosure = str_replace("<iframe", "", $enclosure[0]);

/* turn html content into an array so that we can target the Youtube video id */
		$enclosure = explode("http://www.youtube.com/embed/",$enclosure);
		$enclosure = explode("?", $enclosure[1]);

/* append the video id onto the youtube thumbnail url */
		$final = "<img src='http://img.youtube.com/vi/$enclosure[0]/default.jpg' />";
		?>

/* display thumb wrapped in an anchor */
		<a href="<?php the_permalink(); ?>"><?php echo $final; ?></a>
<?php
	endwhile;
	wp_reset_query();
?>

Eureka Call Library Oracle RightNow get article count per category

Saturday, July 25th, 2015
/**
* Description: Get all categories, display in a list with number of articles in each, alphabetical listing of category level 3
* Date: March 2013
* Classes: GetAllCategories, Generator, Category, CategoryDepot
* Brief Technical:
* Page calls CallLibraryCatList widget
* widget view instantiates GetAllCategories Class, which uses Prodcat model to retrieve categories object
* GetAllCategories Class in turn activates Generator Class
* Generator Class utilizes Category & Category Depot Classes, converting the categories object into instantiated individual category objects that can leverage each other, and then be displayed
*/
class GetAllCategories{
	public $CI;
	public $catListObject;
	public $currentTier = -1;
	public $tier3 = array();
	public $lastLevel = -1;
	public $newLevel = -1;
	public $categoryDepot;

	function __construct() {
		$this->CI =& get_instance();
		$this->CI->load->model('standard/Prodcat_model');
		$this->catListObject = $this->CI->Prodcat_model->getHierPopup(14);
		$this->categoryDepot = new Generator;
		$this->iterateConvert();
	}

	// loops through the returned categories, and uses Generator Class to organize as Category Objects
	function iterateConvert() {
		for( $i=0; $i < count($this->catListObject); $i++ ) {
			if($this->catListObject[$i]['hier_list'] == 588)
			{
				$this->newLevel = $this->catListObject[$i]['level'];

				if ( $this->newLevel < 3 && $this->lastLevel == 3 ) {
					// sort tier 3 alphabetically, then add to collection
					foreach ($this->tier3 as $key => $row) {
						$title[$key] = $row[0];
						$href[$key] = $row['href_list'];
						$level[$key] = $row['level'];
					}
					array_multisort($title, SORT_ASC, $href, SORT_ASC, $level, SORT_ASC, $this->tier3);
					foreach($this->tier3 as $key => $catObject) {
						// create and add tiers 1 & 2 to collection
						$this->categoryDepot->generateCategory($catObject);
					}
					unset($this->tier3);
				}
				if($this->newLevel != 3) {
					// create and add tiers 1 & 2 to collection
					$this->categoryDepot->generateCategory($this->catListObject[$i]);
				}
				if($this->newLevel == 3) {
					// collect tier 3 items
					$this->tier3[] = $this->catListObject[$i];
				}

				$this->lastLevel = $this->newLevel;
				}
			}

			$this->categoryDepot->renderCollection();
		}
	}

class Generator{
	public $categoryDepot;
	public $CI;

	function __construct() {
		$this->categoryDepot = new CategoryDepot;
		$this->CI =& get_instance();
		$this->CI->load->model('custom/AnswersInCategoriesCounter_model');
	}

	function generateCategory($catSent) {
		$category = new Category;
		$category->setTier($catSent['level']);
		$category->setTitle($catSent[0]);
		$categoryArray = $category->setCategories($catSent['hier_list']);
		$finalCategory = $category->getFinalCategory();
		$articleCount = $this->CI->AnswersInCategoriesCounter_model->getCountOfAnswersByCat($finalCategory);
		if($finalCategory != 588 || 0 || null) {
			$this->categoryDepot->addToCollection($category);
		}
		foreach($categoryArray as $key => $categoryId) {
			$this->categoryDepot->updateCategoryArticleCounts($categoryId, $articleCount);
		}
	}	

	function renderCollection() {
		return $this->categoryDepot->getCollection();
	}
}

/**
* $catListObject[$i]['level'] / 0-3
* $catListObject[$i]['hier_list'] / Categories
* $catListObject[$i][0]
*/
class Category {
	public $tier;
	public $categoriesList;
	public $categoryArray;
	public $finalCategory;
	public $title;
	public $parentCategory;
	public $articleCount;
	public $articleTotal;

	function __construct() {
		//echo "Category instantiated";
	}

	function setTier($input) {
		$this->tier = $input;
	}
	
	function setCategories($input) {
		$this->categoriesList = $input;
		$this->setCategoryArray();
		$this->setParentCategory();
		$this->setFinalCategory();
		return $this->categoryArray;
	}

	function setCategoryArray() {
		$this->categoryArray = explode(',',$this->categoriesList);
	}

	function setParentCategory() {
		$itemLevel = $this->tier - 1;
		$this->parentCategory = $this->categoryArray[$itemLevel];
	}

	function setFinalCategory() {
		$this->finalCategory = $this->categoryArray[$this->tier];
	}

	function setTitle($input) {
		$this->title = $input;
	}

	function setArticleCount($input) {
		$newSet = array_unique(array_merge((array)$this->articleCount,(array)$input));
		$this->articleCount = $newSet;
		$this->setArticleTotal();
	}

	function getFinalCategory() { return $this->finalCategory; }
	
	function setArticleTotal() {
		$this->articleTotal = count($this->articleCount);
		return $this->articleTotal;
	}
}

// archives Category Objects, updates each Class's article count, and returns/displays the Collection
class CategoryDepot {
	public $collection;
	public $baseURL = '/app/list_call_library_no_search/r_id/108720/p/646/c/';
	public $currentTier = -1;

	function __construct() {
	}

	function addToCollection($input) {
		$this->collection[] = $input;
	}

	function getCollection() {
		foreach($this->collection as $category) {
			// if articleCount is 0, don't even show count
			if($category->articleTotal != 0){ $articleCount = " (" . $category->articleTotal . ")"; }else{ $articleCount = ''; }

			if($category->tier > $currentTier) {
				$currentTier = $category->tier;
				echo "<ul><li><a href='" . $this->baseURL . $category->categoriesList . "' class='noIntercept'>" . $category->title . $articleCount . "</a>";
			} elseif( $category->tier == $currentTier ) {
				echo "</li><li class='level_" . $category->tier . "'><a href='" . $this->baseURL . $category->categoriesList . "'>" . $category->title . $articleCount . "</a>";
			} elseif($category->tier < $currentTier) {
				$numberToClose = ($currentTier - $category->tier);
				$currentTier = $tier;
				switch ( $numberToClose ) {
					case 1:
						echo "</li></ul></li></ul><ul><li><a href='" . $this->baseURL . $categoriesList . "' class='noIntercept'>" . $category->title . $articleCount . "</a>";
					break;
					case 2:
						echo "</li></ul></li></ul></li></ul><ul><li><a href='" . $this->baseURL . $categoriesList . "' class='noIntercept'>" . $category->title . $articleCount . "</a>";
					break;
				}
			}
		}
	}

	// accepts a finalCategory int and the amount to increment that object's article count
	function updateCategoryArticleCounts($categoryId, $articleCount) {
		foreach ( $this->collection as $category ) {
			if ( $categoryId == $category->finalCategory ) {
				$category->setArticleCount($articleCount);
				break;
			}
		}
	}
}

inArray instead of multiple conditionals or switch case lines: () && () && () && ()

Thursday, December 12th, 2013

Tired of writing


$var != null && $var != undefined &&

forever…?


if( $var != 'NULL' && $var != ' ' && $var != undefined &&....... )

?

or:


switch($var){
case null: break;
case " ": break;
case undefined: break;
...
default:
}

?

Do this instead!


if (!in_array($var, array("", null, "undefined", 'etc.'))){
//
}

Example 2:


$var1 = 50, $var2 = 43, $var4 = 48;
$inProductArray = array($var1, $var2, $var3, $var4);

Instead of:


foreach($inProductArray as $temp){
switch($temp){
case 40:
case 44:
case 48:
case 52: echo "Flight + Hotel"; break;
case 41:
case 45:
case 49:
case 53: echo "Flight"; break;
case 42:
case 46:
case 50:
case 54: echo "Hotel"; break;
case 43:
case 47:
case 51:
case 55: echo = "Car"; break;
}
}// Result HotelCarFlight + Hotel

Do this!


foreach($inProductArray as $temp){
switch($temp){
case in_array($temp, array(40,44,48,52)): echo "Flight + Hotel"; break;
case in_array($temp, array(41,45,49,53)): echo "Flight"; break;
case in_array($temp, array(42,46,50,54)): echo "Hotel"; break;
case in_array($temp, array(43,47,51,55)): echo "Car"; break;
}
}// Result HotelCarFlight + Hotel

PHP SPL FixedArray example

Monday, August 5th, 2013

// Initialize the array with a fixed length
$array = new SplFixedArray(5);

$array[1] = 2;
$array[4] = “foo”;

// Increase the size of the array
$array->setSize(10);

$array[9] = “asdf”;

// Shrink the array to a size of 2
$array->setSize(2);

PHP DoublyLinkedList example

Monday, August 5th, 2013

/*

* Examples of DoublyLinkedList
*/

$obj = new SplDoublyLinkedList();

// Check wither linked list is empty
if ($obj->isEmpty())
{
echo “Adding nodes to Linked List<br>”;
$obj->push(2);
$obj->push(3);

echo “Adding the node at beginning of doubly linked list <br>”;
$obj->unshift(10);
}

echo “<br>Our Linked List:”;
print_r($obj);

echo “<br>Pick the node from beginning of doubly linked list”;
echo $obj->bottom();

/**
Our Linked List:SplDoublyLinkedList Object ( [flags:SplDoublyLinkedList:private] => 0 [dllist:SplDoublyLinkedList:private] => Array ( [0] => 10 [1] => 2 [2] => 3 ) )
Pick the node from beginning of doubly linked list10
*/

Oracle RightNow getNamedValues, get all possible values for answer Object attributes, re-making the console

Thursday, May 16th, 2013

$fields = array(“AccessLevels”, “AnswerType”,”Language”, “StatusWithType.Status”, “Categories”, “Products”);
foreach($fields as $key => $field){
$temp = array();
$$field = array();
$parameter = RNCPHP\ConnectAPI::getNamedValues(“RightNow\\Connect\\v1_2\\Answer”, $field);
foreach($parameter as $key => $value){
$temp[$value->ID] = $value->LookupName;
}
$$field = $temp;
if($field == ‘StatusWithType.Status’){ $StatusWithType = $temp; }
}
// Prove it
foreach($StatusWithType as $key => $value){ echo $key . “, ” . $value . “<br />”; }

// Now fill in the answer creation/edit form values with these values

Test Script Execution Time

Wednesday, May 1st, 2013

// start timing

$mtime = microtime();
$mtime = explode(” “,$mtime);
$mtime = $mtime[1] + $mtime[0];
$starttime = $mtime;

// code to execute

Code to Execute HERE

// revisit timer

$mtime = microtime();
$mtime = explode(” “,$mtime);
$mtime = $mtime[1] + $mtime[0];
$endtime = $mtime;
$totaltime = number_format(($endtime – $starttime),5);

echo “<br /><span style=’display:none;’>Script executed in ” . $totaltime . ” microseconds</span>”;
echo “<br /><span style=’display:none;’>Using ” . memory_get_peak_usage(1) . ” bytes of ram</span>”;

WordPress Functions.php add_filter after comment redirect

Thursday, March 15th, 2012

add_filter(‘comment_post_redirect‘, ‘redirect_after_comment‘);
function redirect_after_comment()
{
wp_redirect($_SERVER[‘HTTP_REFERER‘]);
}

PHP command line accept inputs – $argv

Wednesday, September 28th, 2011

http://php.net/manual/en/reserved.variables.argv.php

example:

~a sudo php scriptname.php 100

pass IN 100 to the script.

In the script, receive input:

$batchNumber = $argv[1]

test it:

var_dump($argv);

handy when calling a php script via a cron, thus allowing the script parameters to be configurable via the cron.

PHP $_Server Host Name etc. command line equivalent

Wednesday, September 28th, 2011

http://php.net/manual/en/function.php-uname.php

string php_uname ([ string $mode = “a” ] )
mode is a single character that defines what information is returned:

  • ‘a’: This is the default. Contains all modes in the sequence “s n r v m”.
  • ‘s’: Operating system name. eg. FreeBSD.
  • ‘n’: Host name. eg. localhost.example.com.
  • ‘r’: Release name. eg. 5.1.2-RELEASE.
  • ‘v’: Version information. Varies a lot between operating systems.
  • ‘m’: Machine type. eg. i386.

Secure HTML form example using PHP htmlentities, passing a token PHP, AJAX submission via jQuery

Wednesday, September 21st, 2011

<? php
// form page (index.php): initialize a session so that we can set a unique, random, encrypted value to a user session
session_start();
$token = md5(uniqid(rand(), true));
$_SESSION[‘token’] = $token;
? >
<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml”>
<head>
<script src=”js/jquery.js” type=”text/javascript”></script>
<script src=”js/jquery.validation.js” type=”text/javascript”></script>
<script src=”js/registerSubmit.js” type=”text/javascript”></script>
</head>
<body>
<!– The Form –>
<form id=”topForm” name=”topForm” method=”post”>
<input type=”hidden” name=”token” id=”token” value=”<? php echo $token; ? >” />
<input name=”emailAddress” id=”emailAddress” value=”Email address” onclick=”if( this.value == ‘Email address’ ){ $(this).val(”); }” onblur=”if( this.value == ”){ $(this).val(‘Email address’); }” />
</form>
</body>
</html>

// The jquery.validation.js class uses a regular expression to stop the process if the email entered isn’t acceptable

;(function($) {
$.validation = {};
$.extend( $.validation, {
email:function(email) {
var filter = /^([a-zA-Z0-9_.-])+@(([a-zA-Z0-9-])+.)+([a-zA-Z0-9]{2,4})+$/;
if ( filter.test(email) ) {
return true;
}
return false;
}
});
})(jQuery);

// The registerSubmit.js submits the entered email via AJAX, returning a success or failure message, to our contactSubmit.php script, which handles the submission of the new email to a database

$(document).ready(function() {

$(“#reg-button”).click(function(){
$(“#topForm”).submit();
});

$(“#topForm”).submit(function(event) {
event.preventDefault();
var $form = $( this ),
emailAddress = $form.find( ‘input[name=”emailAddress”]’ ).val(),
token = $form.find( ‘input[name=”token”]’ ).val(),
formaction = $form.attr( ‘action’ );

if($.validation.email(emailAddress)){
$( “#reg-description” ).html (“submitting…”);
$.ajax({
type: “POST”,
url: “contactSubmit.php”,
data: “firstName=” + firstName + “&lastName=” + lastName + “&emailAddress=” + emailAddress + “&token=” + token,
success: function(){
$( “#reg-description” ).html( “Thank you. You have been registered.” );
},
});
}
else{
$( “#emailAddress” ).val (“Please enter a valid email address”);
}
});
});

// contactSubmit.php:  receive the email, check the token, clean the data, pass to a database layer API

<? php
session_start();

set_include_path(‘DBlayerClass’);
require_once(‘EmailContact.php’);

if (isset($_SESSION[‘token’]) && $_POST[‘token’] == $_SESSION[‘token’]){
if(isset($_POST[’emailAddress’])){
$emailAddress = htmlentities($_POST[’emailAddress’]);
} else { $emailAddress = ”; }

$contact = new EmailContact($emailAddress)

try {
$contact->save();
} catch (Exception $e) {
; // do something
}
//$retrieve = new EmailContact($emailAddress);
//$retrieve->load();
//print_r($retrieve);
//}
? >

PHP retrieving user input when executing a script from the command line

Friday, September 16th, 2011

So either execute the script via the browser, http://someserver/somescript.php
or via the command line >php somescript.php
the example below shows how to support either eventuality

//first we check to see whether the script is being run via the command line, or via a browser

if(defined(‘STDIN‘) ){
echo “Running from CLI” . PHP_EOL;
echo “How many items would you like to batch?”;
$handle = fopen (“php://stdin”,”r”);
$line = fgets($handle);
$batchNumber = trim($line);
// and so on…
}else{
echo “Running from the Browser<br />”;
// and so on…
}

Post via jQuery across domains (in this case to a Zend Controller and subsequent view) and display the results

Thursday, August 25th, 2011

the jQuery posting page, in brief:

<document…>
<head>
<script src=”http://code.jquery.com/jquery-1.5.js”></script>
</head>
<body>
<form id=”enewsform” name=”enewsform” action=”http://componentserver/controllername/post” method=”post”>
<input type=”text” name=”email” id=”email” value=”<?php echo $_REQUEST[’email’]; ?>” />
<a id=”submitsubscribe” title=”Subscribe” href=”javascript:{}” onclick=”return false;”>sign up</a>
</form>
<script src=”http://components.someserver.com/js/jquery.validation.js” type=”text/javascript”></script>
<script>
$(‘#submitsubscribe’).click(function(){
$(“#enewsform”).submit();
});

$(“#enewsform”).submit(function(event) {
event.preventDefault();
$( “#result” ).html (“submitting…”);
var $form = $( this ),
term = $form.find( ‘input[name=”email”]’ ).val(),
url = $form.attr( ‘action’ );

if($.validation.email(term)){
$.getJSON(url + “?email=” + term + “&jsoncallback=?”, function(data){
$( “#result” ).html( data[‘error’] );
if(data[‘error’]== “errormatchingstring”){
$( “#result” ).html( “Seems like it worked” );
}else{ $( “#result” ).html(data[‘error’]); }
});
}
else{ $( “#result” ).html (“Please enter your email address”); }

});
</script>

<div id=”result”></div>

// the component Zend controller in question receives the post, does whatever it does, renders its view, and we access the results from the view (don’t forget to pass data to the view with something like this:
$this-> view-> viewresult = $this-> viewData;)

<? php
echo $_REQUEST[‘jsoncallback’] . ‘(‘ . json_encode($this-> viewresult) . ‘)’;
? >

Bronto API PHP Class to Send a Contact a particular Message (Zend Helper)

Thursday, August 25th, 2011

< ? php
class
Zend_Controller_Action_Helper_BrontoSendMessage extends Zend_Controller_Action_Helper_Abstract {

public $message;
public $client;
public $viewData;
public $list;
public $now = “date(‘c’)”;
public $recipientObject;
public $email;
public $contact;
public $contactId;

private $fromName = ‘WHATEVERYOUWOULDLIKE’;
private $fromEmail = ‘YOU@YOURMAIL.COM’;

public function login(){
ini_set(“soap.wsdl_cache_enabled”, “0”);
date_default_timezone_set(‘America/New_York’);

$wsdl = “https://api.bronto.com/v4?wsdl”;
$url = “https://api.bronto.com/v4”;

$this-> client = new SoapClient($wsdl, array(‘trace’ => 1, ‘encoding’ => ‘UTF-8’));
$this-> client->__setLocation($url);

// Login
$token = “YOUR BRONTO TOKEN HERE”;
$sessionId = $this-> client->login(array(“apiToken” => $token))->return;
if (!$sessionId) {
return “Login failed”;
}
$this-> client->__setSoapHeaders(array(new SoapHeader(“http://api.bronto.com/v4”,
‘sessionHeader’,
array(‘sessionId’ => $sessionId))));

$this-> viewData[‘login’] = “logged in”;
}

public function setContact($email){
$this-> email = $email;

$filter = array(’email’ => array(array(‘operator’ => ‘EqualTo’,’value’ => $this-> email)));

$this-> contact = $this-> client->readContacts(array(‘pageNumber’ => 1,
‘includeLists’ => true,
‘filter’ => $filter,
));
if(!isset($this->contact->return->id))
{
//return ‘Email not subscribed’;
}
else
{
$this-> contactId = $this->contact->return->id;
//return $this->contactId;
}

$this-> recipientObject = array(‘type’ => ‘contact’, ‘id’ => $this->contactId);
}

public function setDelivery($messageid){
$delivery = array(‘start’ => date(‘c’),
‘messageId’ => $messageid,
‘fromName’ => $this-> fromName,
‘fromEmail’ => $this-> fromEmail,
‘recipients’ => array($this-> recipientObject),
);

$this->client->addDeliveries(array($delivery));
}
}
? >

called from another Zend Controller as a helper in this fashion:

$this-> _helper-> BrontoSendMessage->login();
$this-> _helper-> BrontoSendMessage->setContact($this-> email);
$this-> _helper-> BrontoSendMessage->setDelivery($this-> messageid);

Bronto Direct Import API import .csv file (upload) via HTML form post or via PHP CURL with code examples

Tuesday, August 23rd, 2011

We are building a Cassandra based system (of record) to capture emails so that we can handle 100k users converging on an online event as quickly as possible.  Rather than relying on our third party email marketing vendor, Bronto, to handle the volume we could possibly experience, and risk possibly failing (as others doing the same thing recently have done…cough cough….Oprah and Eckhart Tolle), we’ll build our own system that can be tested correctly, and thus handle the volume, and then we’ll dump said new emails in reasonably sized files out to Bronto, who will then send out confirmation emails for us…

This post covers the script that will take file exports from Cassandra (sorry, no Cassandra in this one…), and Post them to Bronto.  Below is an example that uses a standard HTML form Post, for understanding and comprehensiveness, and an example that uses CURL (which easily allows this process to happen as part of an ordinary CRON job).

First we have to set up, and get some connection values, from Bronto:

  • Log into Bronto
  • From the top menu select Home->Settings
  • select Data Exchange
  • scroll to the bottom to Direct Import and grab the following connection values:
    • URL: http://app.bronto.com/mail/subscriber_upload/index/
    • site_id: YOUR_SITE_ID
    • user_id: YOUR_USER_ID
    • key: YOUR_KEY
Further reference, Bronto support docs are here:
https://app.bronto.com/mail/help/help_view/?k=mail:home:api_tracking:tracking_direct_import
 

Next let’s look at what this Post might look like as your common HTML form:

<form method=”post” action=”http://app.bronto.com/mail/subscriber_upload/index/” enctype=”multipart/form-data”>
<input type=”text” name=”source” value=”Test Contacts” />
<input type=”text” name=”format” value=”csv” />
<input type=”file” name=”filename” value=”C:\xampp\htdocs\YOUSITEFOLDERPATH\batch.csv” />
<input type=”text” name=”site_id” value=”YOUR_SITE_ID” />
<input type=”text” name=”user_id” value=”YOUR_USER_ID” />
<input type=”text” name=”key” value=”YOUR_KEY” />
<input type=”submit” name=”submit” value=”submit” />
</form>

Next let’s look at what this Post might look like in a PHP script using CURL:

<? php
$fields = array(
source‘=>”Test contacts“,
format‘=>csv,
filename‘=>’@‘.’C:\xampp\htdocs\YOURSITEFOLDERPATH\batch.csv‘,
site_id‘=>YOUR_SITE_ID,
user_id‘=>YOUR_USER_ID,
key‘=>’YOUR_KEY‘,
);

/* The key here is the ‘@’ above, which tells CURLOPT_POSTFIELDS to UPLOAD that file, parenthesis critical! */

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, ‘http://app.bronto.com/mail/subscriber_upload/index/‘);
curl_setopt($ch, CURLOPT_POST, count($fields));
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
$result = curl_exec($ch);
curl_close($ch);

var_dump($result);
? >

Last but not least, make (or in our case receive from Cassandra export dump) the .csv file to be Posted.
First column, Email, 2nd through n filled with email addresses, save it as .csv comma delineated.
Yes, it’s actually that simple.
I hope this helps somebody.

Create a php page with a form that searches (curls) two separate WordPress applications

Friday, July 29th, 2011

We have many installations where I work, some of them newer, some older, some severely whacked at by coders, some pretty much default installations.

Anyhow, now they want a page from which a visitor could enter a search term, click submit, and get results from all of the separate applications!

Here is my solution:

The new page has your basic self submitting form:

<form action=”” method=”post”>
<label for=”search”>Search:</label>
<input name=”s” type=”text” value=””  />
<input type=”submit” />
</form>

Then, of course, it grabs what has been submitted:

<?php

/**
* Get Search parameters
*/
$search = $_POST[‘s’];
$search = str_replace(” “,”%20”,$search);
echo $search;

?>

This checks to ensure that the user didn’t submit nothing (as WordPress would give us every post as currently coded…! ick).  This would also be a great place to guard against injection attacks (or in the last step of course), to filter what may be searched for, etc., but I’ll leave those concerns for another discussion:

<?php
/**
* If desired search is NOT empty, search, otherwise don’t
*/
if(($search != ”) && ($search != null) && (!empty($search)) )
{
?>

Now we curl in the results from each installation:

<?php
/**
* Get Search results from WP app 1
*/
$sub_req_url = “http://YOURAPP1URLHERE/searchpage.php?s=” . $search;
$ch = curl_init($sub_req_url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$podcast_return = curl_exec($ch);
curl_close($ch);
echo $podcast_return;

/**
* End
*/
?>

<?php
/**
* Get Search results from WP app 2
*/
$sub_req_url = “http://YOURAPP2URLHERE/searchpage.php?s=” . $search;
$ch = curl_init($sub_req_url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$podcast_return = curl_exec($ch);
curl_close($ch);
echo $podcast_return;

/**
* End
*/
?>

Now let’s close our IF block, and maybe provide ELSE if we want to…

<?php
/**
* close if empty block
*/
}
else
{
}
?>

Ok, that’s the end of our new page, again, I’ll leave formatting of the results and the rest of the page to another discussion.  Now let’s make the above mentioned search pages “searchpage.php” (make one for EACH APP, lives in the ROOT of EACH WP installation that we’re searching!):

<?php
/**
* WordPress App 1 Post Results Pull-In
*/
define(‘WP_USE_THEMES‘, true);
include(‘wp-load.php’ );
$query = new WP_Query(‘s=’ . $_GET[‘s’]);
if ($query->have_posts()) : while ($query->have_posts()) : $query->the_post(); ?>

/* Again, how you choose to skin the results could be implemented here, but I’ll leave that up to you… */

<div id=”post-<?php the_ID(); ?>“>
<h2><?php the_title(); ?></h2>
<div>
<?php the_content(‘<p>Read the rest of this page &raquo;</p>‘); ?>
<?php wp_link_pages(array(‘before’ => ‘<p><strong>Pages:</strong> ‘, ‘after’ => ‘</p>‘, ‘next_or_number’ => ‘number’)); ?>
</div>
</div>
<?php endwhile; endif; ?>

Whoohoo! Great Work!

PHP script to download .ics Outlook Event Schedule Calendar Alarm add

Thursday, July 28th, 2011

My boss wanted the ability to put a button on an event on our site that would book it in the user’s Outlook calendar.  Short story is the link downloads an .ics file to their computer, opened with Outlook it schedules the Event, Reminder, Priority, Schedule, and so on.  Thank you http://www.myhow2guru.com

<?php
//This is the most important coding.
header(“Content-Type: text/Calendar”);
header(“Content-Disposition: inline; filename=filename.ics”);
echo “BEGIN:VCALENDAR\n”;
echo “PRODID:-//Microsoft Corporation//Outlook 12.0 MIMEDIR//EN\n”;
echo “VERSION:2.0\n”;
echo “METHOD:PUBLISH\n”;
echo “X-MS-OLK-FORCEINSPECTOROPEN:TRUE\n”;
echo “BEGIN:VEVENT\n”;
echo “CLASS:PUBLIC\n”;
echo “CREATED:20091109T101015Z\n”;
echo “DESCRIPTION:How 2 Guru Event\\n\\n\\nEvent Page\\n\\nhttp://www.myhow2guru.com\n”;
echo “DTEND:20091208T040000Z\n”;
echo “DTSTAMP:20091109T093305Z\n”;
echo “DTSTART:20091208T003000Z\n”;
echo “LAST-MODIFIED:20091109T101015Z\n”;
echo “LOCATION:Anywhere have internet\n”;
echo “PRIORITY:5\n”;
echo “SEQUENCE:0\n”;
echo “SUMMARY;LANGUAGE=en-us:How2Guru Event\n”;
echo “TRANSP:OPAQUE\n”;
echo “UID:040000008200E00074C5B7101A82E008000000008062306C6261CA01000000000000000\n”;
echo “X-MICROSOFT-CDO-BUSYSTATUS:BUSY\n”;
echo “X-MICROSOFT-CDO-IMPORTANCE:1\n”;
echo “X-MICROSOFT-DISALLOW-COUNTER:FALSE\n”;
echo “X-MS-OLK-ALLOWEXTERNCHECK:TRUE\n”;
echo “X-MS-OLK-AUTOFILLLOCATION:FALSE\n”;
echo “X-MS-OLK-CONFTYPE:0\n”;
//Here is to set the reminder for the event.
echo “BEGIN:VALARM\n”;
echo “TRIGGER:-PT1440M\n”;
echo “ACTION:DISPLAY\n”;
echo “DESCRIPTION:Reminder\n”;
echo “END:VALARM\n”;
echo “END:VEVENT\n”;
echo “END:VCALENDAR\n”;
? >

WordPress base url path for multiple platform development links

Thursday, June 30th, 2011

so that anchor tags always nicely point to your application root use:

get_bloginfo('url')

http://codex.wordpress.org/Template_Tags/get_bloginfo

WordPress the_excerpt() strips html tags, create a custom function to leave them in

Friday, May 27th, 2011

go to your theme’s function script:

wp-content/themes/yourthemename/function.php

at the top insert the following (add to ‘<img>’ below to NOT strip out other specific tags, or simply comment the line out…):

function improved_trim_excerpt($text) {
global $post;
if ( ” == $text ) {
$text = get_the_content(”);
$text = apply_filters(‘the_content’, $text);
$text = str_replace(‘]]>’, ‘]]&gt;’, $text);
$text = strip_tags($text, ‘<img>’);
$excerpt_length = 55;
$words = explode(‘ ‘, $text, $excerpt_length + 1);
if (count($words)> $excerpt_length) {
array_pop($words);
array_push($words, ‘[…]’);
$text = implode(‘ ‘, $words);
}
}
return $text;
}
remove_filter(‘get_the_excerpt’,’wp_trim_excerpt’);
add_filter(‘get_the_excerpt’,’improved_trim_excerpt’);

some references: http://codex.wordpress.org/Function_Reference/the_excerpt, http://www.aaronrussell.co.uk/blog/improving-wordpress-the_excerpt/

Create a Facebook App

Thursday, May 26th, 2011

first visit facebook and register your new app:
http://www.facebook.com/developers
configure the facebook settings to point to your server

grab the facebook php library:
http://github.com/facebook/php-sdk/tarball/master
or here:
developers.facebook.com/resources.php

upload your application’s new index.php to your server, something like this:

<? php
require_once ‘facebook.php’;
$appapikey = ‘1234’;
$appsecret = ‘1234’;
$facebook = new Facebook($appapikey, $appsecret);
$user_id = $facebook->require_login(); $html = ‘PUT YOUR HTML HERE’;
$facebook->api_client->profile_setFBML(NULL, $user_id, $html, NULL, NULL, $html);
echo ‘<br /><fb:add-section-button section=”profile” />’;
? >

it’s that simple.

references:

http://www.youtube.com/watch?v=roOYZKsN3Yg
http://www.merchantos.com/blog/makebeta/facebook/facebook-php-tutorial

WordPress convert podcast from Podpress to Powerpress support HTML5 mobile devices

Thursday, May 12th, 2011

If you found this post, you think you’re stuck with Podpress, and/or you’re wanting to make your podcast viewable on mobile devices.  I was in the same boat until just recently, stuck with a podcast I’d initially setup with Podpress years ago, support for which has been worryingly spotty and dwindling, wishing I could now ditch Podpress, but I had over 160 posts I didn’t want to convert….

What I didn’t realize is that the creators of Powerpress had exactly that in mind when they developed Powerpress!  All I had to do was install Powerpress, activate it, ensure that it’s settings were correct, and then deactivate Podpress, and bam, it worked. SO AWESOME, highly recommended.

So I can successfully declare today, that I’ve migrated now 3 podcasts from Podpress to Powerpress, one with 84 posts, one with 164, another with 11.

  • The feeds are unaffected, Feedburner is completely unaware of the change
  • views/layouts unaltered
  • I didn’t even need to go back into the posts and alter the data, Powerpress simply interprets it
  • iTunes unaffected
  • Powerpress serves up the flashplayer if the requesting browser support flash, and theL HTML5 audio or video player if it doesn’t, enabling by many versions of the iPod, iPad, Android, and so on, handled, done!
  • HUGE win.

Persistence of GET URL parameters passed to WordPress site with Permalink clean pretty URLs turned on

Friday, April 15th, 2011

Here’s the scenario:
We have a store site.
The store site has a link on its homepage that leads to a wordpress site.
When a visitor clicks the link,
we want a url parameter that is passed with the visitor to the wordpress site
to remain in the url
so that when/if they click a link in the wordpress site that leads back to the store,
the parameter comes back with them.

Normally, you’d simply add a $_GET in your theme somewhere,
assign it to a variable,
and then append that onto any links that are headed back to the store site.

The trouble, though, is that when WordPress’
clean and pretty Permalinks URL function is active,
it takes over, and forwards (via htaccess, wordpress base code functions, or otherwise),
at which point in time data passed over is lost.

Solution:
In WordPress’ index.php (the very first root directory index),
include another file.

include(‘passback.php’);

In that file, instantiate SERVER SESSIONS, and save received parameters.
Something like this (of course looping through the REQUEST parameters dynamically would be smarter, but for simplicities sake, let’s just target a particular parameter):

session_start();
if($_GET[‘persistme’] != ”){ $passit = $_GET[‘persistme’]; }
if(!isset($_SESSION[‘passback’])){ $_SESSION[‘passback’] = $passit; }

Now you can include your passback retrieval class in your theme, grab the parameter, and use your JavaScript library of choice to loop through all the links in the page and append it onto them.
Something like this (Prototype, and only appending links that already have a ? and thus other parameters they’re sending back…):

document.observe(‘dom:loaded’, function() {
$$(“a”).each(function(a) {
newhref = a.href;
if(newhref.include(‘?’){
newhref = a.href + “?rememberme=<?php echo $passit; ?>”;
a.writeAttribute(‘href’, newhref);
}
});
});

iTunes remove podcast example rss xml feed itunes:block

Thursday, March 3rd, 2011

So you submitted your podcast, with a post containing placeholder content because you had to have it approved and live by some deadline, but now it’s deemed not presentable, because marketing has changed the title last minute, and as you change this first post’s content via its RSS feed, some of it changes, the dynamic parts most likely, the media, and so on, but the title isn’t changing in the iTunes store…

In my example, I used a feedburner feed (iTunes is using that), so I can simply change the feed source in feedburner, to something like the example xml feed in this post, and we can at least get the eyesore out of iTunes, freeing us up to make a new feedburner feed, and re-submit THAT anew to iTunes for a fresh clean go of things…

Host something like this somewhere, and point the old feedburner feed to it, done.

<?xml version=”1.0″ encoding=”UTF-8″?>
<rss xmlns:itunes=”http://www.itunes.com/dtds/podcast-1.0.dtd” version=”2.0″>
<channel>
<itunes:block>yes</itunes:block>
<title>A Title Is Required For The Feed To Validate</title>
</channel>
</rss>

WordPress determine version number

Wednesday, February 23rd, 2011

wp-includes/version.php

WordPress custom sidebar category filtered archive code

Wednesday, February 23rd, 2011

<div id=”sidebar”>
<ul>
<?php
$myposts = get_posts(“category=1”);
foreach($myposts as $post) : ?>
<li><a href=”<?php the_permalink(); ?>“><?php the_time(‘M’) ?>. – <?php the_title(); ?></a></li>
<?php endforeach; ?>
</ul>
</div>

mostly in thanks to:

http://www.z-oc.com/blog/2008/03/category-based-archive/

http://www.themightymo.com/2009/07/22/includeexclude-category-from-wordpress-wp_get_archives/

http://kwebble.com/blog/2007_08_15/archives_for_a_category

WordPress Post to Category ID association in the Database

Wednesday, February 23rd, 2011

WordPress 3

Start with a Post and get Category ID:

Get the id number(A) for the post you’re interested in in wp_posts table,  id column

Go to wp_term_relationships table, and find that same id number(A) in the object_id column, read over to the term_taxonomy_id column and get that number, that’s the category id

Start with a Category ID and get Category Name:

Go to the wp_terms table, and find the category you’d like in the name column, read over to the term_id and note the number

Find all Cateogry IDs:

Go to the wp_term_taxonomy table and sort by taxonomy value ‘category category number is in term_taxonomy_id column

WordPress control number of posts per archive page

Wednesday, February 16th, 2011

edit archive.php

replace this:

< ?php get_header(); ? >

with something along these lines:

< ?php get_header(); ? >
< ?php
$paged = (get_query_var(‘paged’)) ? get_query_var(‘paged’) : 1;
$args=array(
‘showposts’ => 10,
‘paged’=>$paged,
‘caller_get_posts’=> 1
);
query_posts($args);
? >

CakePHP Setting up your system to Bake

Tuesday, February 1st, 2011

http://i.justrealized.com/2009/02/16/how-to-run-xampps-php-cli-and-cakephp-console/
start baking:

C:\xampp\htdocs\project\app>”../cake/console/cake” bake

Starting a new project with CakePHP

Tuesday, February 1st, 2011

download the current release:

cakephp.org

unzip, copy/rename folder as desired

check apache file permissions
app/tmp – 0777

app/config
core.php – change Security.salt to new value
database.php.default – remove .default, and configure values according to your database

done

CakePHP naming conventions

Tuesday, February 1st, 2011

URL will trigger controller
example:
http://appname.com/data_users

in app/controllers:
data_users_controller.php
in there:
class DataUsersController extends Controller {
}

this should be the same as the table it will reference:
data_users

in app/models:
data_user.php
class data_user extends AppModel {
}

in app/views/data_users:
function.ctp

WordPress affect categories search form searches – solution 2

Tuesday, January 18th, 2011

Please see this post if you’re only wanting to limit the form to a single category, as it’s as simple as adding a hidden form field.

This solution uses functions.php, adding something like the following:

function SearchFilter($query)
{
if($query->is_search){
$query->set(‘cat’,’0′);
}
}
add_filter(‘pre_get_posts’,’SearchFilter’);

similar post:
http://alexyz.com/wordpress-rss-feed-exclude-categories-or-only-serve-one-particular-category/

http://alexyz.com/wordpress-limit-search-form-to-a-category-2/

similar reference:

http://speckyboy.com/2010/09/19/10-useful-wordpress-search-code-snippets/

Design Patterns Reference: Visitor

Monday, January 3rd, 2011

“The Visitor Design Pattern constructs distinct objects containing an algorithm that, when consumed by a parent object in a standard way, apply that algorithm to the parent object.”

 

class CD
{
public $band;
public $title;
public $price;

 

public function __construct($band, $title, $price)
{
$this->band = $band;
$this->title = $title;
$this->price = $price;
}

 

public function buy()
{
// stub
}

 

public function acceptVisitor($visitor)
{
$visitor->visitCD($this);
}
}

 

class CDVisitorLogPurchase
{
public function visitCD($cd)
{
$logline = “{$cd->title} by {$cd->band} was purchased for {$cd->price} “;
$logline .= “at ” . sdate(‘r’) . “\n”;

 

file_put_contents(‘/logs/purchases.log’, $logline, FILE_APPEND);
}
}

 

// usage
$externalBand = ‘Never Again’;
$externalTitle = ‘Waste of a Rib’;
$externalPrice = 9.99;

 

$cd = new CD($externalBand, $externalTitle, $externalPrice);
$cd->buy();
$cd->acceptVisitor(new CDVisitorLogPurchase());

 

// adding a new Visitor to accomplish a new functionality is straight forward
class CDVisitorPopulateDiscountList
{
public function visitCD($cd)
{
if ($cd->price < 10)
{
$this->_populateDiscountList($cd);
}
}

 

protected function _populateDiscountList($cd)
{
// stub connects to sqlite and logs etc…
}
}

 

// again, usage
$cd = new CD($externalBand, $externalTitle, $externalPrice);
$cd->buy();
$cd->acceptVisitor(new CDVisitorLogPurchase());
$cd->acceptVisitor(new CDVisitorPopulateDiscountList());

 

source: http://www.wiley.com/WileyCDA/WileyTitle/productCd-0470496703,descCd-DOWNLOAD.html

 

 

WordPress creating users in MySQL via script wp_user_level wp_capabilities wp_users

Monday, January 3rd, 2011

Scenario:
Creating a WordPress blog with an entire company of users.
We want employees to already have an account, so that registration may be turned OFF otherwise.
From an excel list of employees, we’ll extract their email, make an account for each email in the WordPress database, and then they may change their passwords themselves. You can imagine what the php script will look like, to extract the email, and foreach insert the following (uniqueusername and 5 replaced of course with incrementing id numbers and changing emailnames@ourcompany.com):

 

INSERT INTO wp_users
(id,user_login,user_pass,user_email,display_name)
VALUES
(‘5′,’uniqueusername’,md5(‘pass’),’uniqueusername@ourcompany.com’,’uniqueusername’);

 

// to note, this below is simultaneously a nice example of how to insert multiple rows with one MySQL INSERT statement

 

INSERT INTO wp_usermeta
(user_id,meta_key,meta_value)
VALUES
(‘5′,’wp_capabilities’,’a:1:{s:6:”author”;s:1:”1″;}’),
(‘5′,’wp_user_level’,’10’);

 

Thus, the full script looks something like this:

 

$employees = array(’employee1@somesite.com’,’employee2@somesite.com’,’employee3@somesite.com’,’andsoon…’);

 

$startNumber = 10; // if you already have users, pick the next highest number, as it uses this for several tables below, we need them to happen at the same time so that attributes belong to specific users…

 

$db_name = “databasename”;
$db_host = “localhost”;
$db_username = “username”;
$db_password = “password”;

 

// note the nice error reporting so that we can troubleshoot connections, users, table selections, and so forth…
$link = mysql_connect($db_host, $db_username, $db_password);
if (!$link) {
die(‘Could not connect: ‘ . mysql_error());
}
else
{
echo ‘Connected successfully<br />’;
}

 

$db_selected = mysql_select_db($db_name, $link);
if (!$db_selected) {
die (‘Can\’t use foo : ‘ . mysql_error());
}
else
{
echo ‘Selected manyvoices database successfully<br />’;
}

 

foreach($employees as $employee)
{
list($user_name, $therest) = explode(‘@’,$employee);

 

$query1 = “INSERT INTO wp_users
(id,user_login,user_pass,user_email,display_name)
VALUES
(‘” . $startNumber . “‘,'” . $user_name . “‘,md5(‘pass’),'” . $employee . “‘,'” . $user_name . “‘)
“;
//echo $query1 . “<br />”;

 

$result1 = mysql_query($query1);
if(!result1){
die(‘Error: ‘ . mysql_error());
}
else{
echo “User: ” . $user_name . ” : Added<br />”;
}

 

$query2 = “INSERT INTO wp_usermeta
(user_id,meta_key,meta_value)
VALUES
(‘” . $startNumber . “‘,’wp_capabilities’,’a:1:{s:6:\”author\”;s:1:\”1\”;}’),
(‘” . $startNumber . “‘,’wp_user_level’,’10’)
“;
//echo $query2 . “<br />”;

 

$result2 = mysql_query($query2);
if(!result2){
die(‘Error: ‘ . mysql_error());
}
else
{
echo “User Credentials: ” . $user_name . ” : Updated<br />”;
}

 

$startNumber++;
}

 

mysql_close($link);

 

 

Design Patterns Reference: Template

Thursday, December 30th, 2010

“The Template Design Pattern creates an abstract object that enforces a set of methods and functionality that will be used in common by child classes as a template for their own design.”

 

abstract class SaleItemTemplate
{
public $price = 0;

 

public final function setPriceAdjustments()
{
$this->price += $this->taxAddition();
$this->price += $this->oversizedAddition();
}

 

protected function oversizedAddition()
{
return 0;
}

 

abstract protected function taxAddition();
}

 

class CD extends SaleItemTemplate
{
public $band;
public $title;

 

public function __construct($band, $title, $price)
{
$this->band = $band;
$this->title = $title;
$this->price = $price;
}

 

protected function taxAddition()
{
return round($this->price * .05, 2);
}
}

 

class BandEndorsedCaseOfCerial extends SaleItemTemplate
{
public $band;

 

public function __construct($band, $price)
{
$this->band = $band;
$this->price = $price;
}

 

protected function taxAddition()
{
return 0;
}

 

protected function oversizedAddition()
{
return round($this->price * .20, 2);
}
}

 

// use
$externalTitle = “Waste of a Rib”;
$externalBand = “Never Again”;
$externalCDPrice = 12.99;
$externalCerealPrice = 90;
$cd = new CD($externalBand, $exteralTitle, $externalCDPrice);
$cd->setPriceAdjustments();

 

print ‘The total cost for CD item is: $’ . $cd->price;

 

$cereal = new BandEndorsedCaseOfCerial($externalBand, $externalCerealPrice);
$cereal->setPriceAdjustments();

 

print ‘The total cost for the Cereal case is: $’ . $cereal->price;

 

“When creating an object where the general steps of a design are defined but the actual logic is left to be detailed by a child class, using the Template Design Pattern is best practice.”

 

source: http://www.wiley.com/WileyCDA/WileyTitle/productCd-0470496703,descCd-DOWNLOAD.html

 

 

Design Patterns Reference: Strategy

Wednesday, December 29th, 2010

“The Strategy Design Pattern helps architect an object that can make use of algorithms in other objects on demand in lieu of containing the logic itself.”

 

class CDusesStrategy
{
public $title = ”;
public $band = ”;

 

protected $_strategy;

 

public function __construct($title, $band)
{
$this->title = $title;
$this->band = $band;
}

 

public function setStrategyContext($strategyObject)
{
$this->_strategy = $strategyObject;
}

 

public function get()
{
return $this->_strategy->get($this);
}
}

 

class CDAsXMLStrategy
{
public function get(CDusesStrategy $cd)
{
$doc = new DomDocument();
$root = $doc->createElement(‘CD’);
$root = $doc->appendChild($root);
$title = $doc->createElement(‘TITLE’, $cd->title);
$title = $root->appendChild($title);
$band = $root->createElement(‘BAND’, $cd->band);
$band = $root->appendChild($band);

 

return $doc->saveXML();
}
}

 

class CDAsJSONStrategy
{
public function get(CDusesStrategy $cd)
{
$json = array();
$json[‘CD’][‘title’] = $cd->title;
$json[‘CD’][‘band’] = $cd->band;

 

return json_encode($json);
}
}

 

// usage
$cd = new CDusesStrategy($externalTitle, $externalBand);

 

// xml output
$cd->setStrategyContext(new CDAsXMLStrategy());
print $cd->get();

 

// json output
$cd->setStrategyContext(new CDAsJSONStrategy());
print $cd->get($cd);

 

“When it’s possible to create interchangeable objects made of self-contained algorithms to be applied to a base object, it is best practice to use the Strategy Design Pattern”

 

source: http://www.wiley.com/WileyCDA/WileyTitle/productCd-0470496703,descCd-DOWNLOAD.html

 

 

Snippets: HTML object swf embed within a WordPress post snag it n’ publish it code excerpt

Wednesday, December 29th, 2010

<object height=”24″ width=”500″ codebase=”http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0″ classid=”clsid:D27CDB6E-AE6D-11cf-96B8-444553540000″><param value=”file=http://www.site.net/track.mp3&amp;image=http://www.site.net/trackImage.jpg” name=”flashvars”><param value=”http://www.site.com/swf/player.swf” name=”movie”><embed height=”24″ width=”500″ flashvars=”file=http://www.site.net/track.mp3″ pluginspage=”http://www.macromedia.com/go/getflashplayer” type=”application/x-shockwave-flash” src=”http://www.site.com/swf/player.swf”></object>

output XML with PHP (here loaded by Flash)

Tuesday, December 28th, 2010

using something like this in Flash AS perhaps?

playlist.load(“http://www.site.com/playlist.xml”);

wish it were this instead?

playlist.load(“http://www.site.com/playlist.php”);

instead of something like this in xml thus that must be updated…:

<songs><song file=’http://www.site.com/songs/1.mp3′  />
<song file=’http://www.site.com/songs/2.mp3′ /></songs>

you could have something like this, that updates the output xml file each time a new file is added to the songs directory:

< ? p h p

header(‘Content-type:text/xml; charset=utf-8’);
echo “<songs>”;

if ($handle = opendir(‘../songs’)) {
while (false !== ($file = readdir($handle))) {
if ($file != “.” && $file != “..”) {
//echo “$file\n”;
$file_no_extension = implode(‘.’, explode(‘.’, $file, -1));
echo “<song name=’ ” . $file_no_extension . ” ‘ file=’http://www.site.com/songs/” . $file . “‘ />”;
}
}
closedir($handle);
}

echo “</songs>”;
? >

WordPress RSS feed exclude categories or only serve one particular category

Monday, December 27th, 2010

// This will make the site feed ONLY contain category id 9.

add to wp-content/themes/your-active-theme/function.php

function myFilter($query) {
if ($query->is_feed) {
$query->set(‘cat’,’9′);
}
return $query;
}

add_filter(‘pre_get_posts’,’myFilter‘);

// To EXCLUDE categories 9 and 11:

function myFilter($query) {
if ($query->is_feed) {
$query->set(‘cat’,’-9, -11‘);
}
return $query;
}

add_filter(‘pre_get_posts’,’myFilter‘);

WordPress Custom Structure URL Permalinks

Monday, December 13th, 2010

Admin

Settings

Permalinks

Custom Structure radio text entry field

use this:

/%postname%/

so that your posts appear as they do in this blog, here:

http://www.sitename.com/post-name

httpd.conf or .htaccess for apache WordPress redirect

Monday, December 13th, 2010

This is simply a note to save this block of code should I need it again.

The server in question is one of many cloud instances, and local development machines, in an environment using PHP, JAVA, Surf, among other technologies.

In short, it’s a pretty complex implementation/configuration…

Some URLs are being rewritten, others forwarded, directory crawling is off, but…

a legacy WordPress blog is being converted to clean/pretty URLs for SEO purposes

(which “look” like directory folder URLs)

(rather than WordPress relying on URL parameters by default)

so, along with editing the WordPress Setting for this,

the following was added to the httpd.conf file:

<IfModule modrewrite.c>

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ /podcastInQuestionFolder/index.php [L]

</IfModule>

Of course, quite similar code in the .htaccess within that folder would accomplish a similar aim.

WordPress limit search form to a category

Thursday, December 9th, 2010

example:

 

<script>
function submitter()
{
track_it(‘/podcast/searchFormSubmit/’);
document.searchform.submit();
}

</script>

 

<form method=”get” name=”searchform” id=”searchform” action=”<?php bloginfo(‘url’); ?>/”>

 

<input type=”text” value=”<?php the_search_query(); ?>” name=”s” id=”s” onclick=”this.value=””/>

 

This is the important new line, 5 is an example category id

 

<input type=”hidden” name=”cat” value=”5″ />

 

<a href=”javascript:submitter()” style=”text-decoration:none;font-size:11px;margin:0 0 0 5px;position:absolute;top:0px;”><img src=”wp-content/themes/New/images/go.png” onmouseover=”this.src=’wp-content/themes/New/images/go-over.png'” onmouseout=”this.src=’wp-content/themes/New/images/go.png'” border=”0″ />

 

</a>
</form>

 

source: http://wpgarage.com/code-snippets/how-to-hack-the-wordpress-search-function-search-categories-and-child-categories/

 

WordPress Visual editor inactive

Thursday, December 9th, 2010

All of a sudden you can’t click on your visual editor tab when adding a post?
Did you recently install a new plug-in?
Disable it and try again.
It isn’t compatible with your current version…
Just a short note.

Design Patterns Reference: Singleton

Wednesday, December 8th, 2010

“The singleton Design Pattern is used to restrict the number of times a specific object can be created to a single time by providing access to a shared instance of itself.”

 

“The constructor of the object should be a protected method. This will not allow anything but the class itself to create an instance of it. Then it can make a public method to actually create, store, and provide that instance.”

 

Most common use: database connection

 

More interesting possible use, food for thought: configuration option management…

 

class InventoryConnection
{
protected static $_instance = NULL;
protected $_handle = NULL;
public static function getInstance()
{
if(!self::$_instance instanceof self){
self::$_instance = new self;
}
return self::$_instance;
}

 

protected function __construct()
{
$this->_handle = mysql_connect(‘localhost’,’user’,’pass’);
mysql_select_db(‘CD’, $this->_handle);
}

 

public function updateQuantity($band, $title, $number)
{
$query = “update CDS set amount = amount+” . intval($number);
$query .= ” where band=‘ ” . mysql_real_escape_string($band) . ” ‘ “;
$query .= ” and title=‘ ” . mysql_real_escape_string($title) . ” ‘ “;
mysql_query($query, $this->_handle);
}
}

 

class CD
{
protected $_title = ‘ ‘;
protected $_band = ‘ ‘;
public function __construct($title, $band)
{
$this->_title = $title;
$this->_band = $band;
}

 

public function buy()
{
$inventory = InventoryConnection::getInstance();
$inventory->updateQuantity($this->_band, $this->_title, -1);
}
}

 

$boughtCDs = array();
$boughtCDs[] = array(‘band’=>’Never Again’, ‘Waste of a Rib’);
$boughtCDs[] = array(‘band’=>’Therapee’, ‘Long Road’);

 

foreach($boughtCDs as $boughtCD){
$cd = new CD($boughtCD[‘title’], $boughtCD[‘band’]);
$cd->buy();

 

source: http://www.wiley.com/WileyCDA/WileyTitle/productCd-0470496703,descCd-DOWNLOAD.html