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

Last change on this file since 13088 was 12922, checked in by mistic100, 12 years ago

update Piwigo headers to 2012, last change before the expected (or not) apocalypse

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