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

Last change on this file since 8079 was 8079, checked in by patdenice, 13 years ago

feature 2057: fetchRemote can send POST data

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