'Subcategories', 'pi_version' => 'Beta 2', 'pi_author' => 'Maurice Faeh - SHOPLER AG', 'pi_author_url' => 'http://www.shopler.ch/', 'pi_description' => 'Show a list of subcategories for a given category.', 'pi_usage' => Subcategories::usage() ); // ---------------------------------------- // Plugin class // ---------------------------------------- class subcategories { // ---------------------------------------- // mandatory plugin attributes // ---------------------------------------- var $return_data = ''; // ---------------------------------------- // plugin parameter attributes // ---------------------------------------- var $current_node = ''; var $sort_by = ''; var $sort_direction = ''; var $count_entries_from_weblogs = ''; var $count_entries_with_status = ''; var $levels; // ---------------------------------------- // various plugin attributes // ---------------------------------------- // ---------------------------------------- // class constructor // ---------------------------------------- function subcategories() { //return subcategories $this->set_root_node(); $this->set_sort_by(); $this->set_sort_direction(); $this->set_count_entries_with_status(); $this->set_count_entries_from_weblogs(); $this->root_children_nodes(); return $this->return_data; } // ---------------------------------------- // plugin 3rd segment functions // ---------------------------------------- function test() { //return subcategories } // ---------------------------------------- // setter and getter functions // encapsulation for class attributes // ---------------------------------------- function set_return_data() { //encapsulation of return_data attribute } function get_return_data() { //encapsulation of return_data attribute } // ---------------------------------------- function set_root_node($root_node = '') { //encapsulation of root_node attribute global $TMPL; if ($root_node != '') { $this->root_node = $root_node; } else { if ($TMPL->fetch_param('root_node') != '') { $this->root_node = $TMPL->fetch_param('root_node'); } else { $this->root_node = $this->url_root_node(); // Default setting } } } /* validations still missing */ function get_root_node() { //encapsulation of root_node attribute return $this->root_node; } // ---------------------------------------- function set_sort_by($sort_by = '') { //encapsulation of return_data attribute global $TMPL; if ($sort_by != '') { $this->sort_by = $sort_by; } else { if ($TMPL->fetch_param('sort_by') != '') { $this->sort_by = strtolower($TMPL->fetch_param('sort_by')); } else { $this->sort_by = 'category_name'; // Default setting } } } /* validations still missing */ function get_sort_by() { //encapsulation of return_data attribute return $this->sort_by; } // ---------------------------------------- function set_sort_direction($sort_direction = '') { //encapsulation of return_data attribute global $TMPL; if ($sort_direction != '') { $this->sort_direction = $sort_direction; } else { if ($TMPL->fetch_param('sort_direction') != '') { $this->sort_direction = strtolower($TMPL->fetch_param('sort_direction')); } else { $this->sort_direction = 'asc'; // Default setting } } } /* validations still missing */ function get_sort_direction() { //encapsulation of return_data attribute return $this->sort_direction; } // ---------------------------------------- function set_count_entries_from_weblogs($count_entries_from_weblogs = '') { //encapsulation of return_data attribute global $TMPL; if ($count_entries_from_weblogs != '') { $this->count_entries_from_weblogs = $count_entries_from_weblogs; } else { if ($TMPL->fetch_param('count_entries_from_weblogs') != '') { $this->count_entries_from_weblogs = $TMPL->fetch_param('count_entries_from_weblogs'); } else { $this->count_entries_from_weblogs = '22'; // personal default setting } } } /* validations still missing */ function get_count_entries_from_weblogs() { //encapsulation of return_data attribute return $this->count_entries_from_weblogs; } // ---------------------------------------- function set_count_entries_with_status($count_entries_with_status = '') { //encapsulation of return_data attribute global $TMPL; if ($count_entries_with_status != '') { $this->count_entries_with_status = $count_entries_with_status; } else { if ($TMPL->fetch_param('count_entries_with_status') != '') { $this->count_entries_with_status = $TMPL->fetch_param('count_entries_with_status'); } else { $this->count_entries_with_status = 'open'; // Default setting } } } /* validations still missing */ function get_count_entries_with_status() { //encapsulation of return_data attribute return $this->count_entries_with_status; } // ---------------------------------------- function parameter_levels() { //parse levels parameter global $TMPL; if ($TMPL->fetch_param('levels') != '') { return $TMPL->fetch_param('levels'); } else { return 1; // Default setting } } // ---------------------------------------- // various subfunctions // ---------------------------------------- function url_root_node() { //retrieve root_node (i.e. category ID) from URL global $IN; $qstring = $IN->QSTR; // numeric category version //$pattern = "^C(\d+)^"; //originales pattern war "#^C(\d+)#" $pattern = "#^C(\d+)#"; $subject = $qstring; if (preg_match($pattern, $subject, $match)) { $cat_id = $match[1]; //index 0 would output the string "C" as well return $cat_id; } } /* Ab EE 1.3.2 werden angeblich auch Umlaute in der URL berücksichtigt. Daher sollte die Variante wo die aktuelle Kategorie anhand ihres Namens bestimmt wird in Zukunft auch berücksichtigt werden. */ // ---------------------------------------- function root_children_nodes() { //subcategories of root category global $DB, $TMPL, $FNS; $tagdata = $TMPL->tagdata; $sql = "SELECT cat_id, cat_name, cat_url_title, cat_description, cat_image, cat_order FROM exp_categories WHERE exp_categories.parent_id = '".$DB->escape_str($this->get_root_node())."' "; if ($this->sort_by == 'category_name') { $sql .= " ORDER BY cat_name "; } elseif ($this->sort_by == 'category_id') { $sql .= " ORDER BY cat_id "; } elseif ($this->sort_by == 'custom_order') { $sql .= " ORDER BY cat_order "; } if ($this->sort_direction == 'asc') { $sql .= " ASC "; } elseif ($this->sort_direction == 'desc') { $sql .= " DESC "; } $query = $DB->query($sql); if ($query->num_rows > 0) { foreach($query->result as $row) { $tagdata = $TMPL->tagdata; $count_entries = $this->count_entries($row['cat_id']); $count_subcategories = $this->count_subcategories($row['cat_id']); // ---------------------------------------- // parse conditional variable pairs // ---------------------------------------- foreach ($TMPL->var_cond as $val) { $cond = $FNS->prep_conditional($val['0']); $lcond = substr($cond, 0, strpos($cond, ' ')); $rcond = substr($cond, strpos($cond, ' ')); if ($lcond == "entries_count") { eval("\$result = ".$count_entries." ".$rcond.";"); if ($result) { $tagdata = str_replace($val['1'], $val['2'], $tagdata); } //else //{ // $tagdata = ''; //} } } /* Damit die if Klauseln verschachtelt werden könnten müsste hier noch eine rekursive Funktion daraus gemacht werden. */ // ---------------------------------------- // parse single variables // ---------------------------------------- foreach ($TMPL->var_single as $key => $val) { //parse category_id variable if ($key == 'category_id') { if (isset($row['cat_id'])) { $tagdata = $TMPL->swap_var_single($val, $row['cat_id'], $tagdata); //$tagdata = str_replace("/", "/", $tagdata); } } //parse category_name variable if ($key == 'category_name') { if (isset($row['cat_name'])) { $tagdata = $TMPL->swap_var_single($val, $row['cat_name'], $tagdata); //$tagdata = str_replace("/", "/", $tagdata); } } //parse category_url variable if ($key == 'category_url') { if (isset($row['cat_url_title'])) { $tagdata = $TMPL->swap_var_single($val, $row['cat_url_title'], $tagdata); //$tagdata = str_replace("/", "/", $tagdata); } } //parse cat_description variable if ($key == 'category_description') { if (isset($row['cat_description'])) { $tagdata = $TMPL->swap_var_single($val, $row['cat_description'], $tagdata); //$tagdata = str_replace("/", "/", $tagdata); } } //parse cat_description variable if ($key == 'category_image') { if (isset($row['cat_image'])) { $tagdata = $TMPL->swap_var_single($val, $row['cat_image'], $tagdata); //$tagdata = str_replace("/", "/", $tagdata); } } //parse entries_count variable if ($key == 'entries_count') { $tagdata = $TMPL->swap_var_single($val, $count_entries, $tagdata); //$tagdata = str_replace("/", "/", $tagdata); } //parse subcategories_count variable if ($key == 'subcategories_count') { $tagdata = $TMPL->swap_var_single($val, $count_subcategories, $tagdata); //$tagdata = str_replace("/", "/", $tagdata); } // parse template_path variable if (ereg("^template_path", $key)) { $tagdata = $TMPL->swap_var_single($key, $FNS->create_url($FNS->extract_path($key).'/C'.$row['cat_id']), $tagdata); //$tagdata = str_replace("/", "/", $tagdata); } } //$tagdata = str_replace("/", "/", $tagdata); $this->return_data .=$tagdata; } } } // ---------------------------------------- function count_entries($category_id) { //quantity of products per (sub)category global $TMPL, $DB, $FNS; /*original query for one weblog and one status only $sql = "SELECT COUNT(exp_weblog_titles.title) AS count FROM exp_weblog_titles, exp_category_posts WHERE exp_weblog_titles.weblog_id='".$DB->escape_str($this->get_count_entries_from_weblogs())."' AND exp_weblog_titles.status='".$DB->escape_str($this->get_count_entries_with_status())."' AND exp_weblog_titles.entry_id=exp_category_posts.entry_id AND exp_category_posts.cat_id='".$DB->escape_str($category_id)."'"; */ $sql = "SELECT COUNT(exp_weblog_titles.title) AS count FROM exp_weblog_titles, exp_category_posts WHERE exp_weblog_titles.entry_id=exp_category_posts.entry_id AND exp_category_posts.cat_id='".$DB->escape_str($category_id)."' "; $sql .= $FNS->sql_andor_string($DB->escape_str($this->get_count_entries_from_weblogs()), 'weblog_id', 'exp_weblog_titles'); $sql .= $FNS->sql_andor_string($DB->escape_str($this->get_count_entries_with_status()), 'status', 'exp_weblog_titles'); $query = $DB->query($sql); if ($query->row['count'] != '') { $product_quantity = $query->row['count']; return $product_quantity; } } // ---------------------------------------- function count_subcategories($category) { //quantity of subcategories of (sub)category global $DB; $sql = "SELECT COUNT(exp_categories.cat_id) AS count FROM exp_categories WHERE exp_categories.parent_id = '".$DB->escape_str($category)."' "; $query = $DB->query($sql); if ($query->row['count'] != '') { $subcategories_quantity = $query->row['count']; return $subcategories_quantity; } } // ---------------------------------------- // Plugin Usage // ---------------------------------------- function usage() { ob_start(); ?> Introduction: This plugin works like any other ExpressionEngine plugin. Add the following pair of tags to your template. {exp:subcategories}...{/exp:subcategories} Parameters: (1) root_node (2) sort_by (3) sort_direction (4) count_entries_from_weblogs (5) count_entries_with_status Variables: (1) {category_name} (2) {category_id} (3) {category_description} (4) {category_image} (5) {entries_count} (6) {subcategories_count} (7) {template_path="template-group/template"} Conditional Variables: (1) {if entries_count > 5}...{/if} Parameters: (1) The "root_node" parameter: Specify a category other then the category in the URL, of which you want to show subcategories. - Optional - One value only. The ID of any category that you created in EE - Overrides the category ID in the URL *****example***** * * {exp:subcategories root_node="365" ...} *
  • {category_name}
  • * {/exp:subcategories} * ***** * Show the list of subcategories of category 365. * ***** (2) The "sort_by" parameter: Specify a sort order for the list of subcategories. - Optional - One value only. Possible values are "category_name" or "category_id" or "custom_order" - If no value is specified the plugin defaults to "category_name" - If the "custom_order" value is used, the list of subcategories will be sorted according to the custom sort order in the control Panel *****example***** * * {exp:subcategories root_node="365" sort_by="category_name" ...} *
  • {category_name}
  • * {/exp:subcategories} * ***** * Show the list of subcategories of category 365, sorted by the category name. * ***** (3) The "sort_direction" parameter: Specify a sort direction for the list of subcategories. - Optional - One value only. Possible values are "asc" or "desc" - If no value is specified the plugin defaults to "asc" *****example***** * * {exp:subcategories root_node="365" sort_by="category_name" sort_direction="desc" ...} *
  • {category_name}
  • * {/exp:subcategories} * ***** * Show the list of subcategories of category 365, sorted descending by the category name. * ***** (4) The "count_entries_from_weblogs" parameter: Specify which weblogs to include, when counting entries, that are assigned to each subcategory, with the {entries_count} variable. - Mandatory - One or multiple values (separated by the pipe "|" character). The ID(s) of any weblog that you created in EE *****example***** * * {exp:subcategories count_entries_from_weblogs="22|13" ...} *
  • {category_name} - {entries_count}
  • * {/exp:subcategories} * ***** * Show the list of subcategories from the category in the URL. * Show for each subcategory the number of entries that are assigned to it * and belong to the weblogs with the IDs 22 and 13. * ***** (5) The "count_entries_with_status" parameter: Specify what status entries must have, to be counted with the {entries_count} variable. - Optional - One or multiple values (separated by the pipe "|" character). Any status that you created in EE - If no value is specified the plugin defaults to the status "open" *****example***** * * {exp:subcategories count_entries_from_weblogs="22|13" count_entries_with_status="open|closed" ...} *
  • {category_name} - {entries_count}
  • * {/exp:subcategories} * ***** * Show the list of subcategories from the category in the URL. * Show for each subcategory the number of entries that are assigned to it * and belong to the weblogs with the IDs 22 and 13 * and have either status "open" or "closed". * ***** Variables: (1) The {category_name} variable - Optional - The tag of this variable will be replaced with the name of the subcategory *****example***** * * {exp:subcategories root_node="365" ...} *
  • {category_name}
  • * {/exp:subcategories} * ***** * Show a list of subcategories of category 365. * Show the name of each subcategory. * ***** (2) The {category_id} variable - Optional - The tag of this variable will be replaced with the ID of the subcategory *****example***** * * {exp:subcategories root_node="365" ...} *
  • {category_id}
  • * {/exp:subcategories} * ***** * Show a list of subcategories of category 365. * Show the ID of each subcategory. * ***** (3) The {category_description} variable - Optional - The tag of this variable will be replaced with the description of the subcategory *****example***** * * {exp:subcategories root_node="365" ...} *
  • {category_name} - {category_description}
  • * {/exp:subcategories} * ***** * Show a list of subcategories of category 365. * Show the name of each subcategory. * Show the category description of each subcategory. * ***** (4) The {category_image} variable - Optional - The tag of this variable will be replaced with the image url of the subcategory *****example***** * * {exp:subcategories root_node="365" ...} *
  • {category_name} - {category_image}
  • * {/exp:subcategories} * ***** * Show a list of subcategories of category 365. * Show the name of each subcategory. * Show the image url of each subcategory. * ***** (5) The {entries_count} variable - Optional - The tag of this variable will be replaced with the number of entries (specified in the weblogs parameter) that are assigned to the subcategory *****example***** * * {exp:subcategories root_node="365" weblogs="22|13" ...} *
  • {category_name} - {entries_count}
  • * {/exp:subcategories} * ***** * Show a list of subcategories of category 365. * Show the name of each subcategory. * Show the number of entries that are assigned to each subcategory. * ***** (6) The{subcategories_count} variable - Optional - The tag of this variable will be replaced with the number of subcategories that are assigned to the subcategory *****example***** * * {exp:subcategories root_node="365" ...} *
  • {category_name} - {subcategories_count}
  • * {/exp:subcategories} * ***** * Show a list of subcategories of category 365. * Show the name of each subcategory. * Show the number of subcategories that are assigned to each subcategory. * ***** (7) The{template_path="template-group/template"} variable - Optional - The tag of this variable will be replaced with the complete URL to any EE template. *****example***** * * {exp:subcategories root_node="365" ...} *
  • {category_name} - {subcategories_count}
  • * {/exp:subcategories} * ***** * Show a list of subcategories of category 365. * Show the name of each subcategory. * Show the number of subcategories that are assigned to each subcategory. * Add a link to "exampletemplate". * ***** Conditional Variables: (1) The {if entries_count > 5}...{/if} conditional variable - Optional - If testing the condition returns TRUE the content within the conditional variable tag pair will be shown. *****example***** * * {exp:subcategories root_node="365" ...} *
  • {category_name} - {if entries_count > 0}{entries_count}{/if}
  • * {/exp:subcategories} * ***** * Show a list of subcategories of category 365. * Show the name of each subcategory. * If the number of entries that are assigned to each subcategory is bigger than zero show this number of entries. * ***** To do's: (1) nested conditional variables (2) add functionality to accept url categories by name (3) add input type, konstant and other validations to all functions (4) decide to add or not a preset output for many levels (5) add hide_subcategories = x|y|z parameter??? Last Modification 28nd September 2005