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

Last change on this file since 26461 was 26461, checked in by mistic100, 10 years ago

Update headers to 2014. Happy new year!!

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