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

Last change on this file since 2448 was 2299, checked in by plg, 17 years ago

Bug fixed: as rvelices notified me by email, my header replacement script was
bugged (r2297 was repeating new and old header).

By the way, I've also removed the replacement keywords. We were using them
because it was a common usage with CVS but it is advised not to use them with
Subversion. Personnaly, it is a problem when I search differences between 2
Piwigo installations outside Subversion.

  • 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 .= ( strstr($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  if (!isset($params['image_id']))
223  {
224    die('make_picture_url: image_id is a required parameter');
225  }
226
227  $url = get_root_url().'picture';
228  if ($conf['php_extension_in_urls'])
229  {
230    $url .= '.php';
231  }
232  if ($conf['question_mark_in_urls'])
233  {
234    $url .= '?';
235  }
236  $url.= '/';
237  switch ( $conf['picture_url_style'] )
238  {
239    case 'id-file':
240      $url .= $params['image_id'];
241      if ( isset($params['image_file']) )
242      {
243        $url .= '-'.get_filename_wo_extension($params['image_file']);
244      }
245      break;
246    case 'file':
247      if ( isset($params['image_file']) )
248      {
249        $fname_wo_ext = get_filename_wo_extension($params['image_file']);
250        if (! preg_match('/^\d+(-|$)/', $fname_wo_ext) )
251        {
252          $url .= $fname_wo_ext;
253          break;
254        }
255      }
256    default:
257      $url .= $params['image_id'];
258  }
259  if ( !isset($params['category'] ) )
260  {// make urls shorter ...
261    unset( $params['flat'] );
262  }
263  $url .= make_section_in_url($params);
264  $url = add_well_known_params_in_url($url, $params);
265  return $url;
266}
267
268/**
269 *adds to the url the chronology and start parameters
270*/
271function add_well_known_params_in_url($url, $params)
272{
273  if ( isset($params['chronology_field']) )
274  {
275    $url .= '/'. $params['chronology_field'];
276    $url .= '-'. $params['chronology_style'];
277    if ( isset($params['chronology_view']) )
278    {
279      $url .= '-'. $params['chronology_view'];
280    }
281    if ( !empty($params['chronology_date']) )
282    {
283      $url .= '-'. implode('-', $params['chronology_date'] );
284    }
285  }
286
287  if (isset($params['flat']))
288  {
289    $url.= '/flat';
290  }
291
292  if (isset($params['start']) and $params['start'] > 0)
293  {
294    $url.= '/start-'.$params['start'];
295  }
296  return $url;
297}
298
299/**
300 * return the section token of an index or picture URL.
301 *
302 * Depending on section, other parameters are required (see function code
303 * for details)
304 *
305 * @param array
306 * @return string
307 */
308function make_section_in_url($params)
309{
310  global $conf;
311  $section_string = '';
312
313  $section_of = array(
314    'category' => 'categories',
315    'tags'     => 'tags',
316    'list'     => 'list',
317    'search'   => 'search',
318    );
319
320  foreach ($section_of as $param => $section)
321  {
322    if (isset($params[$param]))
323    {
324      $params['section'] = $section;
325    }
326  }
327
328  if (!isset($params['section']))
329  {
330    $params['section'] = 'none';
331  }
332
333  switch($params['section'])
334  {
335    case 'categories' :
336    {
337      if (!isset($params['category']))
338      {
339        $section_string.= '/categories';
340      }
341      else
342      {
343        is_array($params['category']) or trigger_error(
344            'make_section_in_url wrong type for category', E_USER_WARNING
345            );
346        is_numeric($params['category']['id']) or trigger_error(
347            'make_section_in_url category id not numeric', E_USER_WARNING
348            );
349        isset($params['category']['name']) or trigger_error(
350            'make_section_in_url category name not set', E_USER_WARNING
351            );
352
353        array_key_exists('permalink', $params['category']) or trigger_error(
354            'make_section_in_url category permalink not set', E_USER_WARNING
355            );
356
357        $section_string.= '/category/';
358        if ( empty($params['category']['permalink']) )
359        {
360          $section_string.= $params['category']['id'];
361          if ( $conf['category_url_style']=='id-name' )
362          {
363            $section_string.= '-'.str2url($params['category']['name']);
364          }
365        }
366        else
367        {
368          $section_string.= $params['category']['permalink'];
369        }
370      }
371
372      break;
373    }
374    case 'tags' :
375    {
376      if (!isset($params['tags']) or count($params['tags']) == 0)
377      {
378        die('make_section_in_url: require at least one tag');
379      }
380
381      $section_string.= '/tags';
382
383      foreach ($params['tags'] as $tag)
384      {
385        switch ( $conf['tag_url_style'] )
386        {
387          case 'id':
388            $section_string.= '/'.$tag['id'];
389            break;
390          case 'tag':
391            if (isset($tag['url_name']) and !is_numeric($tag['url_name']) )
392            {
393              $section_string.= '/'.$tag['url_name'];
394              break;
395            }
396          default:
397            $section_string.= '/'.$tag['id'];
398            if (isset($tag['url_name']))
399            {
400              $section_string.= '-'.$tag['url_name'];
401            }
402        }
403      }
404
405      break;
406    }
407    case 'search' :
408    {
409      if (!isset($params['search']))
410      {
411        die('make_section_in_url: require a search identifier');
412      }
413
414      $section_string.= '/search/'.$params['search'];
415
416      break;
417    }
418    case 'list' :
419    {
420      if (!isset($params['list']))
421      {
422        die('make_section_in_url: require a list of items');
423      }
424
425      $section_string.= '/list/'.implode(',', $params['list']);
426
427      break;
428    }
429    case 'none' :
430    {
431      break;
432    }
433    default :
434    {
435      $section_string.= '/'.$params['section'];
436    }
437  }
438
439  return $section_string;
440}
441
442/**
443 * the reverse of make_section_in_url
444 * returns the 'section' (categories/tags/...) and the data associated with it
445 *
446 * Depending on section, other parameters are returned (category/tags/list/...)
447 *
448 * @param array of url tokens to parse
449 * @param int the index in the array of url tokens; in/out
450 * @return array
451 */
452function parse_section_url( $tokens, &$next_token)
453{
454  $page=array();
455  if (0 === strpos(@$tokens[$next_token], 'categor'))
456  {
457    $page['section'] = 'categories';
458    $next_token++;
459
460    if (isset($tokens[$next_token]) )
461    {
462      if (preg_match('/^(\d+)(?:-(.+))?$/', $tokens[$next_token], $matches))
463      {
464        if ( isset($matches[2]) )
465          $page['hit_by']['cat_url_name'] = $matches[2];
466        $page['category'] = $matches[1];
467        $next_token++;
468      }
469      else
470      {// try a permalink
471        $maybe_permalinks = array();
472        $current_token = $next_token;
473        while ( isset($tokens[$current_token])
474            and strpos($tokens[$current_token], 'created-')!==0
475            and strpos($tokens[$current_token], 'posted-')!==0
476            and strpos($tokens[$next_token], 'start-')!==0
477            and $tokens[$current_token] != 'flat')
478        {
479          if (empty($maybe_permalinks))
480          {
481            array_push($maybe_permalinks, $tokens[$current_token]);
482          }
483          else
484          {
485            array_push($maybe_permalinks,
486                $maybe_permalinks[count($maybe_permalinks)-1]
487                . '/' . $tokens[$current_token]
488              );
489          }
490          $current_token++;
491        }
492
493        if ( count($maybe_permalinks) )
494        {
495          $cat_id = get_cat_id_from_permalinks($maybe_permalinks, $perma_index);
496          if ( isset($cat_id) )
497          {
498            $next_token += $perma_index+1;
499            $page['category'] = $cat_id;
500            $page['hit_by']['cat_permalink'] = $maybe_permalinks[$perma_index];
501          }
502          else
503          {
504            page_not_found('Permalink for album not found');
505          }
506        }
507      }
508    }
509
510    if (isset($page['category']))
511    {
512      $result = get_cat_info($page['category']);
513      if (empty($result))
514      {
515        page_not_found('Requested category does not exist' );
516      }
517      $page['category']=$result;
518    }
519  }
520  else if (0 === strpos(@$tokens[$next_token], 'tag'))
521  {
522    $page['section'] = 'tags';
523    $page['tags'] = array();
524
525    $next_token++;
526    $i = $next_token;
527
528    $requested_tag_ids = array();
529    $requested_tag_url_names = array();
530
531    while (isset($tokens[$i]))
532    {
533      if ( preg_match('/^(created-|posted-|start-(\d)+)/', $tokens[$i]) )
534        break;
535
536      if ( preg_match('/^(\d+)(?:-(.*))?/', $tokens[$i], $matches) )
537      {
538        array_push($requested_tag_ids, $matches[1]);
539      }
540      else
541      {
542        array_push($requested_tag_url_names, $tokens[$i]);
543      }
544      $i++;
545    }
546    $next_token = $i;
547
548    if ( empty($requested_tag_ids) && empty($requested_tag_url_names) )
549    {
550      bad_request('at least one tag required');
551    }
552
553    $page['tags'] = find_tags($requested_tag_ids, $requested_tag_url_names);
554    if ( empty($page['tags']) )
555    {
556      page_not_found('Requested tag does not exist', get_root_url().'tags.php' );
557    }
558  }
559  else if (0 === strpos(@$tokens[$next_token], 'fav'))
560  {
561    $page['section'] = 'favorites';
562    $next_token++;
563  }
564  else if ('most_visited' == @$tokens[$next_token])
565  {
566    $page['section'] = 'most_visited';
567    $next_token++;
568  }
569  else if ('best_rated' == @$tokens[$next_token])
570  {
571    $page['section'] = 'best_rated';
572    $next_token++;
573  }
574  else if ('recent_pics' == @$tokens[$next_token])
575  {
576    $page['section'] = 'recent_pics';
577    $next_token++;
578  }
579  else if ('recent_cats' == @$tokens[$next_token])
580  {
581    $page['section'] = 'recent_cats';
582    $next_token++;
583  }
584  else if ('search' == @$tokens[$next_token])
585  {
586    $page['section'] = 'search';
587    $next_token++;
588
589    preg_match('/(\d+)/', @$tokens[$next_token], $matches);
590    if (!isset($matches[1]))
591    {
592      bad_request('search identifier is missing');
593    }
594    $page['search'] = $matches[1];
595    $next_token++;
596  }
597  else if ('list' == @$tokens[$next_token])
598  {
599    $page['section'] = 'list';
600    $next_token++;
601
602    $page['list'] = array();
603
604    // No pictures
605    if (empty($tokens[$next_token]))
606    {
607      // Add dummy element list
608      array_push($page['list'], -1);
609    }
610    // With pictures list
611    else
612    {
613      if (!preg_match('/^\d+(,\d+)*$/', $tokens[$next_token]))
614      {
615        bad_request('wrong format on list GET parameter');
616      }
617      foreach (explode(',', $tokens[$next_token]) as $image_id)
618      {
619        array_push($page['list'], $image_id);
620      }
621    }
622    $next_token++;
623  }
624  return $page;
625}
626
627/**
628 * the reverse of add_well_known_params_in_url
629 * parses start, flat and chronology from url tokens
630*/
631function parse_well_known_params_url($tokens, &$i)
632{
633  $page = array();
634  while (isset($tokens[$i]))
635  {
636    if (preg_match('/^start-(\d+)/', $tokens[$i], $matches))
637    {
638      $page['start'] = $matches[1];
639    }
640
641    if ( 'flat' == $tokens[$i] )
642    {
643      // indicate a special list of images
644      $page['flat'] = true;
645    }
646
647    if (preg_match('/^(posted|created)/', $tokens[$i] ))
648    {
649      $chronology_tokens = explode('-', $tokens[$i] );
650
651      $page['chronology_field'] = $chronology_tokens[0];
652
653      array_shift($chronology_tokens);
654      $page['chronology_style'] = $chronology_tokens[0];
655
656      array_shift($chronology_tokens);
657      if ( count($chronology_tokens)>0 )
658      {
659        if ('list'==$chronology_tokens[0] or
660            'calendar'==$chronology_tokens[0])
661        {
662          $page['chronology_view'] = $chronology_tokens[0];
663          array_shift($chronology_tokens);
664        }
665        $page['chronology_date'] = $chronology_tokens;
666      }
667    }
668    $i++;
669  }
670  return $page;
671}
672
673/**
674 * Indicate to build url with full path
675 *
676 * @param null
677 * @return null
678 */
679function set_make_full_url()
680{
681  global $page;
682
683  if (!isset($page['save_root_path']))
684  {
685    if (isset($page['root_path']))
686    {
687      $page['save_root_path']['path'] = $page['root_path'];
688    }
689    $page['save_root_path']['count'] = 1;
690    $page['root_path'] = get_absolute_root_url();
691  }
692  else
693  {
694    $page['save_root_path']['count'] += 1;
695  }
696}
697
698/**
699 * Restore old parameter to build url with full path
700 *
701 * @param null
702 * @return null
703 */
704function unset_make_full_url()
705{
706  global $page;
707
708  if (isset($page['save_root_path']))
709  {
710    if ($page['save_root_path']['count'] == 1)
711    {
712      if (isset($page['save_root_path']['path']))
713      {
714        $page['root_path'] = $page['save_root_path']['path'];
715      }
716      else
717      {
718        unset($page['root_path']);
719      }
720      unset($page['save_root_path']);
721    }
722    else
723    {
724      $page['save_root_path']['count'] -= 1;
725    }
726  }
727}
728
729/**
730 * Embellish the url argument
731 *
732 * @param $url
733 * @return $url embellished
734 */
735function embellish_url($url)
736{
737  return str_replace('/./', '/', $url);
738}
739
740?>
Note: See TracBrowser for help on using the repository browser.