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

Last change on this file since 19703 was 19703, checked in by plg, 11 years ago

update Piwigo headers to 2013 (the end of the world didn't occur as expected on r12922)

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