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

Last change on this file since 14952 was 14180, checked in by rvelices, 13 years ago

"home url" is not always absolute with host name + html compaction - through removal of unused attributes, some white spaces ...

  • Property svn:eol-style set to LF
File size: 18.8 KB
RevLine 
[1109]1<?php
2// +-----------------------------------------------------------------------+
[8728]3// | Piwigo - a PHP based photo gallery                                    |
[2297]4// +-----------------------------------------------------------------------+
[12922]5// | Copyright(C) 2008-2012 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  {
[6411]54    if (isset($_SERVER['HTTPS']) &&
[3403]55        ((strtolower($_SERVER['HTTPS']) == 'on') or ($_SERVER['HTTPS'] == 1)))
[2229]56    {
[3403]57      $url .= 'https://';
[2229]58    }
59    else
60    {
[3403]61      $url .= 'http://';
[2229]62    }
63    $url .= $_SERVER['HTTP_HOST'];
[2083]64    if ($_SERVER['SERVER_PORT'] != 80)
[1750]65    {
[2083]66      $url_port = ':'.$_SERVER['SERVER_PORT'];
67      if (strrchr($url, ':') != $url_port)
68      {
69        $url .= $url_port;
70      }
[1750]71    }
[1566]72  }
[1750]73  $url .= cookie_path();
[1566]74  return $url;
75}
76
77/**
[1109]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 */
[8079]85function add_url_params($url, $params, $arg_separator='&amp;' )
[1109]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;
[8079]96        $url .= ( strpos($url, '?')===false ) ? '?' : $arg_separator;
[1109]97      }
98      else
99      {
[8079]100        $url .= $arg_separator;
[1109]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 */
[1503]118function make_index_url($params = array())
[1109]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  }
[9353]130
131  $url_before_params = $url;
132 
[1503]133  $url.= make_section_in_url($params);
[1109]134  $url = add_well_known_params_in_url($url, $params);
[9353]135
136  if ($url == $url_before_params)
137  {
[14180]138    $url = get_absolute_root_url( url_is_remote($url) );
[9353]139  }
140 
[1109]141  return $url;
142}
143
144/**
145 * build an index URL with current page parameters, but with redefinitions
146 * and removes.
147 *
[1861]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.
[1109]153 *
154 * @param array redefined keys
155 * @param array removed keys
156 * @return string
157 */
[1503]158function duplicate_index_url($redefined = array(), $removed = array())
[1109]159{
[1503]160  return make_index_url(
[1109]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
[3126]176  $params = $page;
[1109]177
[3126]178  foreach ($removed as $param_key)
[1109]179  {
[3126]180    unset($params[$param_key]);
[1109]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
[1503]193 * and removes. See duplicate_index_url.
[1109]194 *
195 * @param array redefined keys
196 * @param array removed keys
197 * @return string
198 */
[1503]199function duplicate_picture_url($redefined = array(), $removed = array())
[1109]200{
[1503]201  return make_picture_url(
[1109]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 */
[1503]212function make_picture_url($params)
[1109]213{
214  global $conf;
215
[2502]216  isset($params['image_id']) or fatal_error('make_picture_url: image_id is a required parameter');
217
[1109]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':
[1562]238      if ( isset($params['image_file']) )
[1109]239      {
[1562]240        $fname_wo_ext = get_filename_wo_extension($params['image_file']);
[2773]241        if ( ord($fname_wo_ext)>ord('9') or !preg_match('/^\d+(-|$)/', $fname_wo_ext) )
[1562]242        {
243          $url .= $fname_wo_ext;
244          break;
245        }
[1109]246      }
247    default:
248      $url .= $params['image_id'];
249  }
[1956]250  if ( !isset($params['category'] ) )
251  {// make urls shorter ...
[2155]252    unset( $params['flat'] );
[1956]253  }
[1503]254  $url .= make_section_in_url($params);
[1109]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
[1800]278  if (isset($params['flat']))
[1677]279  {
[1789]280    $url.= '/flat';
[1677]281  }
282
[1109]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 */
[1503]299function make_section_in_url($params)
[1109]300{
[1131]301  global $conf;
[1109]302  $section_string = '';
[13258]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      );
[1109]312
[13258]313    foreach ($section_of as $param => $s)
314    {
315      if (isset($params[$param]))
316      {
317        $section = $s;
318      }
319    }
[1119]320
[13258]321    if (!isset($section))
322    {
323      $section = 'none';
324    }
325  }
[1109]326
[13240]327  switch($section)
[1109]328  {
329    case 'categories' :
330    {
331      if (!isset($params['category']))
332      {
[1119]333        $section_string.= '/categories';
[1109]334      }
335      else
336      {
[1861]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
[1866]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']) )
[1131]353        {
[1866]354          $section_string.= $params['category']['id'];
355          if ( $conf['category_url_style']=='id-name' )
356          {
357            $section_string.= '-'.str2url($params['category']['name']);
358          }
[1131]359        }
[1866]360        else
361        {
362          $section_string.= $params['category']['permalink'];
363        }
[1109]364      }
365
366      break;
367    }
368    case 'tags' :
369    {
370      if (!isset($params['tags']) or count($params['tags']) == 0)
371      {
[2502]372        fatal_error('make_section_in_url: require at least one tag');
[1109]373      }
374
375      $section_string.= '/tags';
376
377      foreach ($params['tags'] as $tag)
378      {
[1131]379        switch ( $conf['tag_url_style'] )
[1119]380        {
[1131]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            }
[1119]396        }
[1109]397      }
398
399      break;
400    }
401    case 'search' :
402    {
[2502]403      isset($params['search']) or fatal_error('make_section_in_url: require a search identifier');
[1109]404      $section_string.= '/search/'.$params['search'];
405      break;
406    }
407    case 'list' :
408    {
[2502]409      isset($params['list']) or fatal_error('make_section_in_url: require a list of items');
[1109]410      $section_string.= '/list/'.implode(',', $params['list']);
411      break;
412    }
[1788]413    case 'none' :
414    {
415      break;
416    }
[1109]417    default :
418    {
[13240]419      $section_string.= '/'.$section;
[1109]420    }
421  }
422
423  return $section_string;
424}
[1676]425
426/**
[1980]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();
[2773]439  if (strncmp(@$tokens[$next_token], 'categor', 7)==0 )
[1980]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
[2047]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
[1980]460            and strpos($tokens[$next_token], 'start-')!==0
[2047]461            and $tokens[$current_token] != 'flat')
462        {
463          if (empty($maybe_permalinks))
464          {
465            array_push($maybe_permalinks, $tokens[$current_token]);
[1980]466          }
[2047]467          else
468          {
469            array_push($maybe_permalinks,
470                $maybe_permalinks[count($maybe_permalinks)-1]
471                . '/' . $tokens[$current_token]
472              );
473          }
474          $current_token++;
475        }
476
477        if ( count($maybe_permalinks) )
478        {
479          $cat_id = get_cat_id_from_permalinks($maybe_permalinks, $perma_index);
[1980]480          if ( isset($cat_id) )
481          {
[2047]482            $next_token += $perma_index+1;
[1980]483            $page['category'] = $cat_id;
[2047]484            $page['hit_by']['cat_permalink'] = $maybe_permalinks[$perma_index];
[1980]485          }
486          else
487          {
488            page_not_found('Permalink for album not found');
489          }
490        }
[2047]491      }
[1980]492    }
493
494    if (isset($page['category']))
495    {
496      $result = get_cat_info($page['category']);
497      if (empty($result))
498      {
499        page_not_found('Requested category does not exist' );
500      }
501      $page['category']=$result;
502    }
503  }
[2773]504  elseif ( 'tags' == @$tokens[$next_token] )
[1980]505  {
[11831]506    global $conf;
507
[1980]508    $page['section'] = 'tags';
509    $page['tags'] = array();
510
511    $next_token++;
512    $i = $next_token;
513
514    $requested_tag_ids = array();
515    $requested_tag_url_names = array();
516
517    while (isset($tokens[$i]))
518    {
[2773]519      if (strpos($tokens[$i], 'created-')===0
520           or strpos($tokens[$i], 'posted-')===0
521           or strpos($tokens[$i], 'start-')===0 )
[1980]522        break;
523
[11831]524      if ( $conf['tag_url_style'] != 'tag' and preg_match('/^(\d+)(?:-(.*)|)$/', $tokens[$i], $matches) )
[1980]525      {
526        array_push($requested_tag_ids, $matches[1]);
527      }
528      else
529      {
530        array_push($requested_tag_url_names, $tokens[$i]);
531      }
532      $i++;
533    }
534    $next_token = $i;
535
536    if ( empty($requested_tag_ids) && empty($requested_tag_url_names) )
537    {
538      bad_request('at least one tag required');
539    }
540
541    $page['tags'] = find_tags($requested_tag_ids, $requested_tag_url_names);
542    if ( empty($page['tags']) )
543    {
544      page_not_found('Requested tag does not exist', get_root_url().'tags.php' );
545    }
546  }
[2773]547  elseif ( 'favorites' == @$tokens[$next_token] )
[1980]548  {
549    $page['section'] = 'favorites';
550    $next_token++;
551  }
[2773]552  elseif ('most_visited' == @$tokens[$next_token])
[1980]553  {
554    $page['section'] = 'most_visited';
555    $next_token++;
556  }
[2773]557  elseif ('best_rated' == @$tokens[$next_token])
[1980]558  {
559    $page['section'] = 'best_rated';
560    $next_token++;
561  }
[2773]562  elseif ('recent_pics' == @$tokens[$next_token])
[1980]563  {
564    $page['section'] = 'recent_pics';
565    $next_token++;
566  }
[2773]567  elseif ('recent_cats' == @$tokens[$next_token])
[1980]568  {
569    $page['section'] = 'recent_cats';
570    $next_token++;
571  }
[2773]572  elseif ('search' == @$tokens[$next_token])
[1980]573  {
574    $page['section'] = 'search';
575    $next_token++;
576
577    preg_match('/(\d+)/', @$tokens[$next_token], $matches);
578    if (!isset($matches[1]))
579    {
580      bad_request('search identifier is missing');
581    }
582    $page['search'] = $matches[1];
583    $next_token++;
584  }
[2773]585  elseif ('list' == @$tokens[$next_token])
[1980]586  {
587    $page['section'] = 'list';
588    $next_token++;
589
590    $page['list'] = array();
591
592    // No pictures
593    if (empty($tokens[$next_token]))
594    {
595      // Add dummy element list
596      array_push($page['list'], -1);
597    }
598    // With pictures list
599    else
600    {
601      if (!preg_match('/^\d+(,\d+)*$/', $tokens[$next_token]))
602      {
603        bad_request('wrong format on list GET parameter');
604      }
605      foreach (explode(',', $tokens[$next_token]) as $image_id)
606      {
607        array_push($page['list'], $image_id);
608      }
609    }
610    $next_token++;
611  }
612  return $page;
613}
614
615/**
616 * the reverse of add_well_known_params_in_url
617 * parses start, flat and chronology from url tokens
618*/
[2155]619function parse_well_known_params_url($tokens, &$i)
[1980]620{
621  $page = array();
622  while (isset($tokens[$i]))
623  {
624    if ( 'flat' == $tokens[$i] )
625    {
626      // indicate a special list of images
627      $page['flat'] = true;
628    }
[2773]629    elseif (strpos($tokens[$i], 'created-')===0 or strpos($tokens[$i], 'posted-')===0)
[1980]630    {
631      $chronology_tokens = explode('-', $tokens[$i] );
632
633      $page['chronology_field'] = $chronology_tokens[0];
634
635      array_shift($chronology_tokens);
636      $page['chronology_style'] = $chronology_tokens[0];
637
638      array_shift($chronology_tokens);
639      if ( count($chronology_tokens)>0 )
640      {
641        if ('list'==$chronology_tokens[0] or
642            'calendar'==$chronology_tokens[0])
643        {
644          $page['chronology_view'] = $chronology_tokens[0];
645          array_shift($chronology_tokens);
646        }
647        $page['chronology_date'] = $chronology_tokens;
648      }
649    }
[2773]650    elseif (preg_match('/^start-(\d+)/', $tokens[$i], $matches))
651    {
652      $page['start'] = $matches[1];
653    }
[1980]654    $i++;
655  }
656  return $page;
657}
658
[12855]659
[1980]660/**
[12855]661 * @param id image id
662 * @param what_part string one of 'e' (element), 'r' (representative)
663 */
664function get_action_url($id, $what_part, $download)
665{
666  $params = array(
667        'id' => $id,
668        'part' => $what_part,
669      );
670  if ($download)
671  {
672    $params['download'] = null;
673  }
674 
675  return add_url_params(get_root_url().'action.php', $params);
676}
677
678/*
679 * @param element_info array containing element information from db;
680 * at least 'id', 'path' should be present
681 */
682function get_element_url($element_info)
683{
684  $url = $element_info['path'];
685  if ( !url_is_remote($url) )
686  {
687    $url = embellish_url(get_root_url().$url);
688  }
689  return $url;
690}
691
692
693/**
[1676]694 * Indicate to build url with full path
695 *
696 * @param null
697 * @return null
698 */
699function set_make_full_url()
700{
701  global $page;
702
703  if (!isset($page['save_root_path']))
704  {
705    if (isset($page['root_path']))
706    {
707      $page['save_root_path']['path'] = $page['root_path'];
708    }
709    $page['save_root_path']['count'] = 1;
[1750]710    $page['root_path'] = get_absolute_root_url();
[1676]711  }
712  else
713  {
714    $page['save_root_path']['count'] += 1;
715  }
716}
717
718/**
719 * Restore old parameter to build url with full path
720 *
721 * @param null
722 * @return null
723 */
724function unset_make_full_url()
725{
726  global $page;
727
728  if (isset($page['save_root_path']))
729  {
730    if ($page['save_root_path']['count'] == 1)
731    {
732      if (isset($page['save_root_path']['path']))
733      {
734        $page['root_path'] = $page['save_root_path']['path'];
735      }
736      else
737      {
738        unset($page['root_path']);
739      }
740      unset($page['save_root_path']);
741    }
742    else
743    {
744      $page['save_root_path']['count'] -= 1;
745    }
746  }
747}
748
[2026]749/**
750 * Embellish the url argument
751 *
752 * @param $url
753 * @return $url embellished
754 */
755function embellish_url($url)
756{
[3126]757  $url = str_replace('/./', '/', $url);
758  while ( ($dotdot = strpos($url, '/../', 1) ) !== false )
759  {
760    $before = strrpos($url, '/', -(strlen($url)-$dotdot+1) );
761    if ($before !== false)
762    {
763      $url = substr_replace($url, '', $before, $dotdot-$before+3);
764    }
765    else
766      break;
767  }
768  return $url;
[2026]769}
770
[6411]771/**
772 * Returns the 'home page' of this gallery
773 */
774function get_gallery_home_url()
775{
776  global $conf;
777  if (!empty($conf['gallery_url']))
778  {
[8247]779    if (url_is_remote($conf['gallery_url']) or $conf['gallery_url'][0]=='/' )
[6411]780    {
781      return $conf['gallery_url'];
782    }
783    return get_root_url().$conf['gallery_url'];
784  }
785  else
786  {
787    return make_index_url();
788  }
789}
[3126]790?>
Note: See TracBrowser for help on using the repository browser.