source: trunk/include/functions_url.inc.php @ 2786

Last change on this file since 2786 was 2773, checked in by rvelices, 16 years ago

merge rev 2771,2772 from branch 2.0

  • 2771 event tracer improvement: option to show all registered event handlers for every page
  • 2772 php optims (small): remove/replace preg_xxx with faster simple string functions
  • Property svn:eol-style set to LF
  • Property svn:keywords set to Author Date Id Revision
File size: 17.4 KB
Line 
1<?php
2// +-----------------------------------------------------------------------+
3// | Piwigo - a PHP based picture gallery                                  |
4// +-----------------------------------------------------------------------+
5// | Copyright(C) 2008      Piwigo Team                  http://piwigo.org |
6// | Copyright(C) 2003-2008 PhpWebGallery Team    http://phpwebgallery.net |
7// | Copyright(C) 2002-2003 Pierrick LE GALL   http://le-gall.net/pierrick |
8// +-----------------------------------------------------------------------+
9// | This program is free software; you can redistribute it and/or modify  |
10// | it under the terms of the GNU General Public License as published by  |
11// | the Free Software Foundation                                          |
12// |                                                                       |
13// | This program is distributed in the hope that it will be useful, but   |
14// | WITHOUT ANY WARRANTY; without even the implied warranty of            |
15// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU      |
16// | General Public License for more details.                              |
17// |                                                                       |
18// | You should have received a copy of the GNU General Public License     |
19// | along with this program; if not, write to the Free Software           |
20// | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, |
21// | USA.                                                                  |
22// +-----------------------------------------------------------------------+
23
24
25/**
26 * returns a prefix for each url link on displayed page
27 * and return an empty string for current path
28 * @return string
29 */
30function get_root_url()
31{
32  global $page;
33  if ( isset($page['root_path']) )
34  {
35    $root_url = $page['root_path'];
36  }
37  else
38  {// TODO - add HERE the possibility to call PWG functions from external scripts
39    $root_url = PHPWG_ROOT_PATH;
40  }
41  if ( dirname($root_url)!='.' )
42  {
43    return $root_url;
44  }
45  else
46  {
47    return (string)substr($root_url, 2);
48  }
49}
50
51/**
52 * returns the absolute url to the root of PWG
53 * @param boolean with_scheme if false - does not add http://toto.com
54 */
55function get_absolute_root_url($with_scheme=true)
56{
57  // TODO - add HERE the possibility to call PWG functions from external scripts
58  $url = '';
59  if ($with_scheme)
60  {
61    if (empty($_SERVER['HTTPS']))
62    {
63      $url .= 'http://';
64    }
65    else
66    {
67      $url .= 'https://';
68    }
69    $url .= $_SERVER['HTTP_HOST'];
70    if ($_SERVER['SERVER_PORT'] != 80)
71    {
72      $url_port = ':'.$_SERVER['SERVER_PORT'];
73      if (strrchr($url, ':') != $url_port)
74      {
75        $url .= $url_port;
76      }
77    }
78  }
79  $url .= cookie_path();
80  return $url;
81}
82
83/**
84 * adds one or more _GET style parameters to an url
85 * example: add_url_params('/x', array('a'=>'b')) returns /x?a=b
86 * add_url_params('/x?cat_id=10', array('a'=>'b')) returns /x?cat_id=10&amp;a=b
87 * @param string url
88 * @param array params
89 * @return string
90 */
91function add_url_params($url, $params)
92{
93  if ( !empty($params) )
94  {
95    assert( is_array($params) );
96    $is_first = true;
97    foreach($params as $param=>$val)
98    {
99      if ($is_first)
100      {
101        $is_first = false;
102        $url .= ( strpos($url, '?')===false ) ? '?' :'&amp;';
103      }
104      else
105      {
106        $url .= '&amp;';
107      }
108      $url .= $param;
109      if (isset($val))
110      {
111        $url .= '='.$val;
112      }
113    }
114  }
115  return $url;
116}
117
118/**
119 * build an index URL for a specific section
120 *
121 * @param array
122 * @return string
123 */
124function make_index_url($params = array())
125{
126  global $conf;
127  $url = get_root_url().'index';
128  if ($conf['php_extension_in_urls'])
129  {
130    $url .= '.php';
131  }
132  if ($conf['question_mark_in_urls'])
133  {
134    $url .= '?';
135  }
136  $url.= make_section_in_url($params);
137  $url = add_well_known_params_in_url($url, $params);
138  return $url;
139}
140
141/**
142 * build an index URL with current page parameters, but with redefinitions
143 * and removes.
144 *
145 * duplicate_index_url( array(
146 *   'category' => array('id'=>12, 'name'=>'toto'),
147 *   array('start')
148 * ) will create an index URL on the current section (categories), but on
149 * a redefined category and without the start URL parameter.
150 *
151 * @param array redefined keys
152 * @param array removed keys
153 * @return string
154 */
155function duplicate_index_url($redefined = array(), $removed = array())
156{
157  return make_index_url(
158    params_for_duplication($redefined, $removed)
159    );
160}
161
162/**
163 * returns $page global array with key redefined and key removed
164 *
165 * @param array redefined keys
166 * @param array removed keys
167 * @return array
168 */
169function params_for_duplication($redefined, $removed)
170{
171  global $page;
172
173  if (count($removed) > 0)
174  {
175    $params = array();
176
177    foreach ($page as $page_item_key => $page_item_value)
178    {
179      if (!in_array($page_item_key, $removed))
180      {
181        $params[$page_item_key] = $page_item_value;
182      }
183    }
184  }
185  else
186  {
187    $params = $page;
188  }
189
190  foreach ($redefined as $redefined_param => $redefined_value)
191  {
192    $params[$redefined_param] = $redefined_value;
193  }
194
195  return $params;
196}
197
198/**
199 * create a picture URL with current page parameters, but with redefinitions
200 * and removes. See duplicate_index_url.
201 *
202 * @param array redefined keys
203 * @param array removed keys
204 * @return string
205 */
206function duplicate_picture_url($redefined = array(), $removed = array())
207{
208  return make_picture_url(
209    params_for_duplication($redefined, $removed)
210    );
211}
212
213/**
214 * create a picture URL on a specific section for a specific picture
215 *
216 * @param array
217 * @return string
218 */
219function make_picture_url($params)
220{
221  global $conf;
222
223  isset($params['image_id']) or fatal_error('make_picture_url: image_id is a required parameter');
224
225  $url = get_root_url().'picture';
226  if ($conf['php_extension_in_urls'])
227  {
228    $url .= '.php';
229  }
230  if ($conf['question_mark_in_urls'])
231  {
232    $url .= '?';
233  }
234  $url.= '/';
235  switch ( $conf['picture_url_style'] )
236  {
237    case 'id-file':
238      $url .= $params['image_id'];
239      if ( isset($params['image_file']) )
240      {
241        $url .= '-'.get_filename_wo_extension($params['image_file']);
242      }
243      break;
244    case 'file':
245      if ( isset($params['image_file']) )
246      {
247        $fname_wo_ext = get_filename_wo_extension($params['image_file']);
248        if ( ord($fname_wo_ext)>ord('9') or !preg_match('/^\d+(-|$)/', $fname_wo_ext) )
249        {
250          $url .= $fname_wo_ext;
251          break;
252        }
253      }
254    default:
255      $url .= $params['image_id'];
256  }
257  if ( !isset($params['category'] ) )
258  {// make urls shorter ...
259    unset( $params['flat'] );
260  }
261  $url .= make_section_in_url($params);
262  $url = add_well_known_params_in_url($url, $params);
263  return $url;
264}
265
266/**
267 *adds to the url the chronology and start parameters
268*/
269function add_well_known_params_in_url($url, $params)
270{
271  if ( isset($params['chronology_field']) )
272  {
273    $url .= '/'. $params['chronology_field'];
274    $url .= '-'. $params['chronology_style'];
275    if ( isset($params['chronology_view']) )
276    {
277      $url .= '-'. $params['chronology_view'];
278    }
279    if ( !empty($params['chronology_date']) )
280    {
281      $url .= '-'. implode('-', $params['chronology_date'] );
282    }
283  }
284
285  if (isset($params['flat']))
286  {
287    $url.= '/flat';
288  }
289
290  if (isset($params['start']) and $params['start'] > 0)
291  {
292    $url.= '/start-'.$params['start'];
293  }
294  return $url;
295}
296
297/**
298 * return the section token of an index or picture URL.
299 *
300 * Depending on section, other parameters are required (see function code
301 * for details)
302 *
303 * @param array
304 * @return string
305 */
306function make_section_in_url($params)
307{
308  global $conf;
309  $section_string = '';
310
311  $section_of = array(
312    'category' => 'categories',
313    'tags'     => 'tags',
314    'list'     => 'list',
315    'search'   => 'search',
316    );
317
318  foreach ($section_of as $param => $section)
319  {
320    if (isset($params[$param]))
321    {
322      $params['section'] = $section;
323    }
324  }
325
326  if (!isset($params['section']))
327  {
328    $params['section'] = 'none';
329  }
330
331  switch($params['section'])
332  {
333    case 'categories' :
334    {
335      if (!isset($params['category']))
336      {
337        $section_string.= '/categories';
338      }
339      else
340      {
341        is_array($params['category']) or trigger_error(
342            'make_section_in_url wrong type for category', E_USER_WARNING
343            );
344        is_numeric($params['category']['id']) or trigger_error(
345            'make_section_in_url category id not numeric', E_USER_WARNING
346            );
347        isset($params['category']['name']) or trigger_error(
348            'make_section_in_url category name not set', E_USER_WARNING
349            );
350
351        array_key_exists('permalink', $params['category']) or trigger_error(
352            'make_section_in_url category permalink not set', E_USER_WARNING
353            );
354
355        $section_string.= '/category/';
356        if ( empty($params['category']['permalink']) )
357        {
358          $section_string.= $params['category']['id'];
359          if ( $conf['category_url_style']=='id-name' )
360          {
361            $section_string.= '-'.str2url($params['category']['name']);
362          }
363        }
364        else
365        {
366          $section_string.= $params['category']['permalink'];
367        }
368      }
369
370      break;
371    }
372    case 'tags' :
373    {
374      if (!isset($params['tags']) or count($params['tags']) == 0)
375      {
376        fatal_error('make_section_in_url: require at least one tag');
377      }
378
379      $section_string.= '/tags';
380
381      foreach ($params['tags'] as $tag)
382      {
383        switch ( $conf['tag_url_style'] )
384        {
385          case 'id':
386            $section_string.= '/'.$tag['id'];
387            break;
388          case 'tag':
389            if (isset($tag['url_name']) and !is_numeric($tag['url_name']) )
390            {
391              $section_string.= '/'.$tag['url_name'];
392              break;
393            }
394          default:
395            $section_string.= '/'.$tag['id'];
396            if (isset($tag['url_name']))
397            {
398              $section_string.= '-'.$tag['url_name'];
399            }
400        }
401      }
402
403      break;
404    }
405    case 'search' :
406    {
407      isset($params['search']) or fatal_error('make_section_in_url: require a search identifier');
408      $section_string.= '/search/'.$params['search'];
409      break;
410    }
411    case 'list' :
412    {
413      isset($params['list']) or fatal_error('make_section_in_url: require a list of items');
414      $section_string.= '/list/'.implode(',', $params['list']);
415      break;
416    }
417    case 'none' :
418    {
419      break;
420    }
421    default :
422    {
423      $section_string.= '/'.$params['section'];
424    }
425  }
426
427  return $section_string;
428}
429
430/**
431 * the reverse of make_section_in_url
432 * returns the 'section' (categories/tags/...) and the data associated with it
433 *
434 * Depending on section, other parameters are returned (category/tags/list/...)
435 *
436 * @param array of url tokens to parse
437 * @param int the index in the array of url tokens; in/out
438 * @return array
439 */
440function parse_section_url( $tokens, &$next_token)
441{
442  $page=array();
443  if (strncmp(@$tokens[$next_token], 'categor', 7)==0 )
444  {
445    $page['section'] = 'categories';
446    $next_token++;
447
448    if (isset($tokens[$next_token]) )
449    {
450      if (preg_match('/^(\d+)(?:-(.+))?$/', $tokens[$next_token], $matches))
451      {
452        if ( isset($matches[2]) )
453          $page['hit_by']['cat_url_name'] = $matches[2];
454        $page['category'] = $matches[1];
455        $next_token++;
456      }
457      else
458      {// try a permalink
459        $maybe_permalinks = array();
460        $current_token = $next_token;
461        while ( isset($tokens[$current_token])
462            and strpos($tokens[$current_token], 'created-')!==0
463            and strpos($tokens[$current_token], 'posted-')!==0
464            and strpos($tokens[$next_token], 'start-')!==0
465            and $tokens[$current_token] != 'flat')
466        {
467          if (empty($maybe_permalinks))
468          {
469            array_push($maybe_permalinks, $tokens[$current_token]);
470          }
471          else
472          {
473            array_push($maybe_permalinks,
474                $maybe_permalinks[count($maybe_permalinks)-1]
475                . '/' . $tokens[$current_token]
476              );
477          }
478          $current_token++;
479        }
480
481        if ( count($maybe_permalinks) )
482        {
483          $cat_id = get_cat_id_from_permalinks($maybe_permalinks, $perma_index);
484          if ( isset($cat_id) )
485          {
486            $next_token += $perma_index+1;
487            $page['category'] = $cat_id;
488            $page['hit_by']['cat_permalink'] = $maybe_permalinks[$perma_index];
489          }
490          else
491          {
492            page_not_found('Permalink for album not found');
493          }
494        }
495      }
496    }
497
498    if (isset($page['category']))
499    {
500      $result = get_cat_info($page['category']);
501      if (empty($result))
502      {
503        page_not_found('Requested category does not exist' );
504      }
505      $page['category']=$result;
506    }
507  }
508  elseif ( 'tags' == @$tokens[$next_token] )
509  {
510    $page['section'] = 'tags';
511    $page['tags'] = array();
512
513    $next_token++;
514    $i = $next_token;
515
516    $requested_tag_ids = array();
517    $requested_tag_url_names = array();
518
519    while (isset($tokens[$i]))
520    {
521      if (strpos($tokens[$i], 'created-')===0
522           or strpos($tokens[$i], 'posted-')===0
523           or strpos($tokens[$i], 'start-')===0 )
524        break;
525
526      if ( preg_match('/^(\d+)(?:-(.*))?/', $tokens[$i], $matches) )
527      {
528        array_push($requested_tag_ids, $matches[1]);
529      }
530      else
531      {
532        array_push($requested_tag_url_names, $tokens[$i]);
533      }
534      $i++;
535    }
536    $next_token = $i;
537
538    if ( empty($requested_tag_ids) && empty($requested_tag_url_names) )
539    {
540      bad_request('at least one tag required');
541    }
542
543    $page['tags'] = find_tags($requested_tag_ids, $requested_tag_url_names);
544    if ( empty($page['tags']) )
545    {
546      page_not_found('Requested tag does not exist', get_root_url().'tags.php' );
547    }
548  }
549  elseif ( 'favorites' == @$tokens[$next_token] )
550  {
551    $page['section'] = 'favorites';
552    $next_token++;
553  }
554  elseif ('most_visited' == @$tokens[$next_token])
555  {
556    $page['section'] = 'most_visited';
557    $next_token++;
558  }
559  elseif ('best_rated' == @$tokens[$next_token])
560  {
561    $page['section'] = 'best_rated';
562    $next_token++;
563  }
564  elseif ('recent_pics' == @$tokens[$next_token])
565  {
566    $page['section'] = 'recent_pics';
567    $next_token++;
568  }
569  elseif ('recent_cats' == @$tokens[$next_token])
570  {
571    $page['section'] = 'recent_cats';
572    $next_token++;
573  }
574  elseif ('search' == @$tokens[$next_token])
575  {
576    $page['section'] = 'search';
577    $next_token++;
578
579    preg_match('/(\d+)/', @$tokens[$next_token], $matches);
580    if (!isset($matches[1]))
581    {
582      bad_request('search identifier is missing');
583    }
584    $page['search'] = $matches[1];
585    $next_token++;
586  }
587  elseif ('list' == @$tokens[$next_token])
588  {
589    $page['section'] = 'list';
590    $next_token++;
591
592    $page['list'] = array();
593
594    // No pictures
595    if (empty($tokens[$next_token]))
596    {
597      // Add dummy element list
598      array_push($page['list'], -1);
599    }
600    // With pictures list
601    else
602    {
603      if (!preg_match('/^\d+(,\d+)*$/', $tokens[$next_token]))
604      {
605        bad_request('wrong format on list GET parameter');
606      }
607      foreach (explode(',', $tokens[$next_token]) as $image_id)
608      {
609        array_push($page['list'], $image_id);
610      }
611    }
612    $next_token++;
613  }
614  return $page;
615}
616
617/**
618 * the reverse of add_well_known_params_in_url
619 * parses start, flat and chronology from url tokens
620*/
621function parse_well_known_params_url($tokens, &$i)
622{
623  $page = array();
624  while (isset($tokens[$i]))
625  {
626    if ( 'flat' == $tokens[$i] )
627    {
628      // indicate a special list of images
629      $page['flat'] = true;
630    }
631    elseif (strpos($tokens[$i], 'created-')===0 or strpos($tokens[$i], 'posted-')===0)
632    {
633      $chronology_tokens = explode('-', $tokens[$i] );
634
635      $page['chronology_field'] = $chronology_tokens[0];
636
637      array_shift($chronology_tokens);
638      $page['chronology_style'] = $chronology_tokens[0];
639
640      array_shift($chronology_tokens);
641      if ( count($chronology_tokens)>0 )
642      {
643        if ('list'==$chronology_tokens[0] or
644            'calendar'==$chronology_tokens[0])
645        {
646          $page['chronology_view'] = $chronology_tokens[0];
647          array_shift($chronology_tokens);
648        }
649        $page['chronology_date'] = $chronology_tokens;
650      }
651    }
652    elseif (preg_match('/^start-(\d+)/', $tokens[$i], $matches))
653    {
654      $page['start'] = $matches[1];
655    }
656    $i++;
657  }
658  return $page;
659}
660
661/**
662 * Indicate to build url with full path
663 *
664 * @param null
665 * @return null
666 */
667function set_make_full_url()
668{
669  global $page;
670
671  if (!isset($page['save_root_path']))
672  {
673    if (isset($page['root_path']))
674    {
675      $page['save_root_path']['path'] = $page['root_path'];
676    }
677    $page['save_root_path']['count'] = 1;
678    $page['root_path'] = get_absolute_root_url();
679  }
680  else
681  {
682    $page['save_root_path']['count'] += 1;
683  }
684}
685
686/**
687 * Restore old parameter to build url with full path
688 *
689 * @param null
690 * @return null
691 */
692function unset_make_full_url()
693{
694  global $page;
695
696  if (isset($page['save_root_path']))
697  {
698    if ($page['save_root_path']['count'] == 1)
699    {
700      if (isset($page['save_root_path']['path']))
701      {
702        $page['root_path'] = $page['save_root_path']['path'];
703      }
704      else
705      {
706        unset($page['root_path']);
707      }
708      unset($page['save_root_path']);
709    }
710    else
711    {
712      $page['save_root_path']['count'] -= 1;
713    }
714  }
715}
716
717/**
718 * Embellish the url argument
719 *
720 * @param $url
721 * @return $url embellished
722 */
723function embellish_url($url)
724{
725  return str_replace('/./', '/', $url);
726}
727
728?>
Note: See TracBrowser for help on using the repository browser.