I’ve set-up a directory for a client. It allows information to be viewed in a variety of manners. One proposed manner is by topic. ‘By Topic’ is like a combination between categories and keywords. Basically, each topic has a set of pre-defined keywords, each keyword is searched upon. For example, the topic, disability housing might be defined with the following keywords.
Disability Housing: disabilities, fair housing, accessible, discrimination, disabled, section 8, hud
The goal is to allow the client to define topics as needed, so the topics are stored in a weblog, which consist of three fields: title, url_title, and topic_keywords.
Basically, how the plug-in needs to work is to accept data from the topic weblog, and then perform a query against another weblog. So in this example, we have the weblog topics, and the weblog programs, there is also a weblog called locations. I have PHP code that explodes the keywords and creates a mega-WHERE component for the SELECT statement, the problem is, it requires PHP parsing on in and out to grab the topic create the WHERE component, then run the final SELECT statement. So all my research shows this is a job for a plug-in. But even after reading through the plug-in development information, I’m kind of lost.
I’m going to provide some of the PHP code in hopes that someone might be willing to hold my hand a little bit.
Here’s the grabbing of the keywords.
{exp:weblog:entries weblog="topics" limit="1"}
<?php
error_reporting(E_ALL ^ E_NOTICE);
$in_keywords = '{topic_keywords}'; // string
if (!empty($in_keywords)) {
// need a separate, temporary array for these so we can wrap JUST these in extra parens
$keyword_wheres = array();
if ($in_exact_keyword == 'y') {
// search on exactly what was entered in the keyword field
$keywords = mysql_real_escape_string($in_keywords);
$keyword_wheres[] = "(exp_weblog_titles.title LIKE '%$keywords%' OR
exp_weblog_data.field_id_1 LIKE '%$keywords%' OR
exp_weblog_data.field_id_2 LIKE '%$keywords%' OR
exp_weblog_data.field_id_10 LIKE '%$keywords%' OR
exp_weblog_data.field_id_140 LIKE '%$keywords%' OR
exp_weblog_data.field_id_157 LIKE '%$keywords%')";
} else {
// tokenize the keywords and search individually
$keywords = explode(' ', $in_keywords);
for ($i = 0; $i < count($keywords); $i++) {
$keyword = $keywords[$i];
$keyword_wheres[] = "(exp_weblog_titles.title LIKE '%$keyword%' OR
exp_weblog_data.field_id_1 LIKE '%$keyword%' OR
exp_weblog_data.field_id_2 LIKE '%$keyword%' OR
exp_weblog_data.field_id_10 LIKE '%$keyword%' OR
exp_weblog_data.field_id_140 LIKE '%$keyword%' OR
exp_weblog_data.field_id_157 LIKE '%$keyword%')";
}
}
// add an extra paren to the front of the first keyword_where,
// and the end of the last one
$keyword_wheres[0] = '(' . $keyword_wheres[0];
$last_index = count($keyword_wheres) - 1;
$keyword_wheres[$last_index] = $keyword_wheres[$last_index] . ')';
// tack these onto the $wheres entries
$wheres = array_merge($wheres, $keyword_wheres);
}
// we have all the bits, now build them into a full where clause
$whereClause = 'WHERE ';
// make sure the operator is legit
if (!in_array($in_operator, array('OR', 'AND'))) {
$op = ' AND ';
} else {
$op = " $in_operator ";
}
if (count($wheres) > 0) {
foreach ($wheres as $clause) {
$whereClause .= $clause . $op;
}
$whereClause = substr($whereClause, 0, (0 - strlen($op)));
} else {
$whereClause = 'WHERE 1 = 0';
}
?>
{/exp:weblog:entries}
Here’s the code for the final query, the <?=$whereClause?> is where the WHERE clause is added.
<ol>
{exp:query sql="SELECT exp_weblogs.blog_name, exp_weblog_titles.entry_id, exp_weblog_titles.title AS title, exp_weblog_titles.url_title AS url_title, exp_weblog_data.field_id_157 AS city, exp_weblog_data.field_id_158 AS state, exp_weblog_data.field_id_138 AS description, exp_weblog_data.field_id_140 AS keywords, exp_weblog_data.field_id_143 AS region, exp_weblog_data.field_id_144 AS subsite, exp_categories.cat_name AS category
FROM ((((exp_weblogs LEFT JOIN exp_weblog_titles ON exp_weblogs.weblog_id=exp_weblog_titles.weblog_id) LEFT JOIN exp_weblog_data ON exp_weblog_titles.entry_id=exp_weblog_data.entry_id) LEFT JOIN exp_category_posts ON exp_weblog_data.entry_id=exp_category_posts.entry_id) LEFT JOIN exp_categories ON exp_category_posts.cat_id=exp_categories.cat_id)
<?=$whereClause?> AND exp_weblog_titles.status='open' AND exp_weblog_titles.weblog_id IN ('34','35') AND exp_weblog_data.field_id_144 LIKE '%{subsite_id}%'
ORDER BY exp_categories.cat_name ASC, exp_weblog_titles.title ASC"}
<li><a href="http://{domain}/articles/{url_title}">{title}</a></li>
{/exp:query}
</ol>
I’ve shrunk the code down a little, so I may have removed a necessary } or something. But the full code works, creating a functioning WHERE statement for use. It’s basically an adaption from a custom keyword search designed by another developer for the same project.
What I’m not certain is:
(1) Would this required paired plugin call, like {exp:plugin:topic}{/exp:plugin:topic}? (2) If so, would I place the paired call around the page that display the topics? (3) Should the plugin focus on the first half-collecting the topic and creating the query or the second half, executing the query?
Lots of question, anyone willing to help a bit?
Packet Tide owns and develops ExpressionEngine. © Packet Tide, All Rights Reserved.