source: trunk/lib/Navigation.inc.php @ 523

Last change on this file since 523 was 523, checked in by anonymous, 9 years ago

First set of changes towards 2.2.0. Improved functinoality with integration in wordpress; bugs fixed.

File size: 14.3 KB
Line 
1<?php
2/**
3 * The Strangecode Codebase - a general application development framework for PHP
4 * For details visit the project site: <http://trac.strangecode.com/codebase/>
5 * Copyright 2001-2012 Strangecode, LLC
6 *
7 * This file is part of The Strangecode Codebase.
8 *
9 * The Strangecode Codebase is free software: you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as published by the
11 * Free Software Foundation, either version 3 of the License, or (at your option)
12 * any later version.
13 *
14 * The Strangecode Codebase is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
17 * details.
18 *
19 * You should have received a copy of the GNU General Public License along with
20 * The Strangecode Codebase. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23/**
24 * Navigation.inc.php
25 *
26 * The Nav class provides a system for working with navigation elements.
27 * It supports storing page titles and URLs for printing breadcrumbs
28 * and titles, as well as setting page params such as hiding the page title on
29 * some pages but not others, and storing vars like the page title itself.
30 *
31 * Note: this class was renamed from "Nav" because of the change in API and to be more descriptive.
32 *
33 * @author  Quinn Comendant <quinn@strangecode.com>
34 * @version 2.0
35 */
36class Navigation
37{
38
39    // Configuration parameters for this object.
40    protected $_params = array(
41        'head_title' => true,
42        'body_title' => true,
43        'title' => true,
44        'path' => true,
45        'breadcrumbs' => true,
46        'chop_breadcrumbs' => 0,
47        'chop_breadcrumb_links' => 1,
48        'path_delimiter' => ' / ',
49        'last_crumb_format' => '%s',
50    );
51    public $pages = array();
52
53    /**
54     * Navigation constructor.
55     */
56    public function __construct($params=null)
57    {
58        $app =& App::getInstance();
59
60        if (isset($params) && is_array($params)) {
61            // Merge new parameters with old overriding only those passed.
62            $this->_params = array_merge($this->_params, $params);
63        }
64    }
65
66    /**
67     * Add a page to the internal pages array. Pages must be added sequentially
68     * as they are to be printed. The root page must be added first, and the
69     * current page added last. Vars can be specified for any page, but only vars
70     * from the "current" page will be accessed with Nav::get.
71     *
72     * @access  public
73     * @param   string  $title      The title of the page.
74     * @param   string  $url        The URL to the page. Set to null to use PHP_SELF.
75     * @param   array   $vars       Additional page variables.
76     */
77    public function add($title, $url=null, $vars=array())
78    {
79        $page = array(
80            'title' => $title,
81            'head_title' => $title,
82            'body_title' => $title,
83            'url' => is_null($url) ? $_SERVER['PHP_SELF'] : $url,
84        );
85        $this->pages[] = array_merge($page, $vars);
86    }
87
88    /**
89     * Set (or overwrite existing) parameters by passing an array of new parameters.
90     *
91     * @access public
92     * @param  array    $params     Array of parameters (key => val pairs).
93     */
94    public function setParam($params)
95    {
96        $app =& App::getInstance();
97
98        if (isset($params) && is_array($params)) {
99            // Merge new parameters with old overriding only those passed.
100            $this->_params = array_merge($this->_params, $params);
101        } else {
102            $app->logMsg(sprintf('Parameters are not an array: %s', $params), LOG_ERR, __FILE__, __LINE__);
103        }
104    }
105
106    /**
107     * Return the value of a parameter, if it exists.
108     *
109     * @access public
110     * @param string $param        Which parameter to return.
111     * @return mixed               Configured parameter value.
112     */
113    public function getParam($param)
114    {
115        $app =& App::getInstance();
116
117        if (array_key_exists($param, $this->_params)) {
118            return $this->_params[$param];
119        } else {
120            $app->logMsg(sprintf('Parameter is not set: %s', $param), LOG_DEBUG, __FILE__, __LINE__);
121            return null;
122        }
123    }
124
125    /**
126     * Unsets all pages.
127     *
128     * @access  public
129     */
130    public function clear()
131    {
132        $this->pages = array();
133    }
134
135    /**
136     * Sets a variable into the current page.
137     *
138     * @access public
139     * @param mixed $key      Which value to set.
140     * @param mixed $val      Value to set variable to.
141     */
142    public function set($key, $val)
143    {
144        // Set params of current page.
145        $curr_page =& $this->pages[sizeof($this->pages) - 1];
146        $curr_page[$key] = $val;
147    }
148
149    /**
150     * Returns a specified value from the current page.
151     *
152     * @access public
153     * @param mixed $key      Which value to return.
154     * @param mixed $default  Value to return if key not found in user_data.
155     * @return mixed          Value stored in session.
156     */
157    public function get($key, $default='')
158    {
159        $curr_page =& $this->pages[sizeof($this->pages) - 1];
160
161        switch ($key) {
162        case 'title' :
163            if ($this->getParam('title') && isset($curr_page['title'])) {
164                return $curr_page['title'];
165            }
166            break;
167
168        case 'head_title' :
169            if ($this->getParam('head_title') && $this->getParam('title') && isset($curr_page['head_title'])) {
170                return $curr_page['head_title'];
171            }
172            break;
173
174        case 'body_title' :
175            if ($this->getParam('body_title') && $this->getParam('title') && isset($curr_page['body_title'])) {
176                return $curr_page['body_title'];
177            }
178            break;
179
180        case 'path' :
181            if ($this->getParam('path')) {
182                return $this->getPath();
183            }
184            break;
185
186        case 'breadcrumbs' :
187            if ($this->getParam('breadcrumbs')) {
188                return $this->getBreadcrumbs();
189            }
190            break;
191
192        default :
193            return isset($curr_page[$key]) ? $curr_page[$key] : $default;
194            break;
195        }
196
197        return $default;
198    }
199
200    /**
201     * Returns the path from root up to the current page as an array.
202     *
203     * @access  public
204     * @param   string   $key   Which value to use in the path (usually head_title or body_title or just title).
205     * @return  mixed           Path (string) or false if path param is not set.
206     */
207    public function getPathArray($key='title')
208    {
209        $path = array();
210        if ($this->getParam('path')) {
211            foreach ($this->pages as $page) {
212                $path[] = strip_tags($page[$key]);
213            }
214        }
215        return $path;
216    }
217
218    /**
219     * Returns the text path from root up to the current page, separated by the
220     * path_delimiter.
221     *
222     * @access  public
223     * @param   string   $key   Which value to use in the path (usually head_title or body_title or just title).
224     * @return  mixed           Path (string) or false if path param is not set.
225     */
226    public function getPath($key='title')
227    {
228
229        $path = $this->getPathArray();
230        return empty($path) ? '' : join(oTxt($this->getParam('path_delimiter'), true), $path);
231    }
232
233    /**
234     * Returns the breadcrumbs from the root page to the current page.
235     * Breadcrumbs are the text path with pages titles linked to that page.
236     *
237     * @access  public
238     * @return  string   Breadcrumbs or empty string if breadcrumbs param not set.
239     */
240    public function getBreadcrumbsArray()
241    {
242        $app =& App::getInstance();
243
244        if ($this->getParam('breadcrumbs')) {
245            $breadcrumbs = array();
246            $crumb_count = sizeof($this->pages);
247            foreach ($this->pages as $page) {
248                if ($crumb_count <= $this->getParam('chop_breadcrumbs')) {
249                    // Stop gathering crumbs.
250                    break;
251                }
252                if ($crumb_count <= 1) {
253                    // The last crumb.
254                    if ('' == trim($page['url']) || $crumb_count <= $this->getParam('chop_breadcrumb_links')) {
255                        // A crumb with no link.
256                        $breadcrumbs[] = array(
257                            'url' => $_SERVER['REQUEST_URI'],
258                            'title' => sprintf($this->getParam('last_crumb_format'), $page['title']),
259                            'class' => 'current'
260                        );
261                    } else if ($crumb_count > $this->getParam('chop_breadcrumb_links')) {
262                        // A normal linked crumb.
263                        $breadcrumbs[] = array(
264                            'url' => $page['url'],
265                            'title' => sprintf($this->getParam('last_crumb_format'), $page['title']),
266                            'class' => '',
267                        );
268                    }
269                } else {
270                    if ('' == trim($page['url'])) {
271                        // A crumb with no link.
272                        $breadcrumbs[] = array(
273                            'url' => false,
274                            'title' => $page['title'],
275                            'class' => 'unavailable',
276                        );
277                    } else {
278                        // A normal linked crumb.
279                        $breadcrumbs[] = array(
280                            'url' => $page['url'],
281                            'title' => $page['title'],
282                            'class' => '',
283                        );
284                    }
285                }
286                $crumb_count--;
287            }
288            return $breadcrumbs;
289        } else {
290            return array();
291        }
292    }
293
294    /**
295     * Returns the breadcrumbs from the root page to the current page.
296     * Breadcrumbs are the text path with pages titles linked to that page.
297     *
298     * @access  public
299     * @return  string   Breadcrumbs or empty string if breadcrumbs param not set.
300     */
301    public function getBreadcrumbs()
302    {
303        $app =& App::getInstance();
304
305        if ($this->getParam('breadcrumbs')) {
306            $breadcrumbs = array();
307            $pathmark = '';
308            $crumb_count = sizeof($this->pages);
309            foreach ($this->pages as $page) {
310                if ($crumb_count <= $this->getParam('chop_breadcrumbs')) {
311                    // Stop gathering crumbs.
312                    break;
313                }
314                if ($crumb_count <= 1) {
315                    // The last crumb.
316                    if ('' == trim($page['url']) || $crumb_count <= $this->getParam('chop_breadcrumb_links')) {
317                        // A crumb with no link.
318                        $breadcrumbs[] =  sprintf($this->getParam('last_crumb_format'), oTxt($page['title'], true));
319                    } else if ($crumb_count > $this->getParam('chop_breadcrumb_links')) {
320                        // A normal linked crumb.
321                        $breadcrumbs[] =  '<a href="' . $page['url'] . '">' . sprintf($this->getParam('last_crumb_format'), oTxt($page['title'], true)) . '</a>';
322                    }
323                } else {
324                    if ('' == trim($page['url'])) {
325                        // A crumb with no link.
326                        $breadcrumbs[] = oTxt($pathmark . $page['title'], true);
327                    } else {
328                        // A normal linked crumb.
329                        $breadcrumbs[] = '<a href="' . $page['url'] . '">' . oTxt($page['title'], true) . '</a>';
330                    }
331                }
332                $pathmark = $this->getParam('path_delimiter');
333                $crumb_count--;
334            }
335            return join(oTxt($pathmark, true), $breadcrumbs);
336        } else {
337            return '';
338        }
339    }
340
341    /*
342    *
343    *
344    * @access   public
345    * @param
346    * @return
347    * @author   Quinn Comendant <quinn@strangecode.com>
348    * @version  1.0
349    * @since    07 Sep 2014 12:22:19
350    */
351    public function getBreadcrumbsUL()
352    {
353        $out = '';
354        $breadcrumbs = $this->getBreadcrumbsArray();
355        if (!empty($breadcrumbs)) {
356            $out = '<ul class="breadcrumbs">';
357            foreach ($breadcrumbs as $b) {
358                $printclass = '' != $b['class'] ? sprintf(' class="%s"', $b['class']) : '';
359                $out .= sprintf('<li%s><a href="%s">%s</a></li>', $printclass, $b['url'], $b['title']);
360            }
361            $out .= '</ul>';
362        }
363        return $out;
364    }
365
366    /**
367     * Test if the given URI matches the URL of the current page. By default the URI is tested
368     * without concern
369     * One use is to change the returned value for a positive match
370     * so a css class prints for an element representing the current page:
371     *   echo $nav->currentPage('/script.php?op=info', ' class="current"', '', true);
372     * The above will match only if the current page (REQUEST_URI) is also '/script.php?op=info',
373     * and will return the string ' class="current"' if it is.
374     *
375     * @access  public
376     *
377     * @param   string  $test_uri       A URI to test against the current page.
378     * @param   mixed   $true_return    The value to return if the current page matches the test URI.
379     * @param   mixed   $false_return   The value to return if the current page does not match the test URI.
380     * @param   bool    $include_query  If set true, include the URI query string in the test.
381     *
382     * @return  mixed   If the test URI matches the current page URI, the value given for $true_return
383     *                  is returned (true by default), otherwise the value given for $false_return is
384     *                  returned (false by default).
385     */
386    public function currentPage($test_uri, $true_return=true, $false_return=false, $include_query=false)
387    {
388        $app =& App::getInstance();
389
390        $actual_uri = $include_query ? $_SERVER['REQUEST_URI'] : strtok($_SERVER['REQUEST_URI'], '?');
391        $test_uri = $include_query ? $test_uri : strtok($test_uri, '?');
392        if (mb_strtolower($test_uri) == mb_strtolower($actual_uri)) {
393            // $app->logMsg(sprintf('Current page (%s) == test URI (%s)', $actual_uri, $test_uri), LOG_DEBUG, __FILE__, __LINE__);
394            return $true_return;
395        }
396        // $app->logMsg(sprintf('Current page (%s) != test URI (%s)', $actual_uri, $test_uri), LOG_DEBUG, __FILE__, __LINE__);
397        return $false_return;
398    }
399
400}
401// End of class.
Note: See TracBrowser for help on using the repository browser.